Kokkos Core Kernels Package  Version of the Day
Kokkos_DynRankView.hpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44 
50 
51 #ifndef KOKKOS_DYNRANKVIEW_HPP
52 #define KOKKOS_DYNRANKVIEW_HPP
53 
54 #include <Kokkos_Core.hpp>
55 #include <impl/Kokkos_Error.hpp>
56 #include <type_traits>
57 
58 namespace Kokkos {
59 
60 template <typename DataType, class... Properties>
61 class DynRankView; // forward declare
62 
63 namespace Impl {
64 
65 template <typename Specialize>
66 struct DynRankDimTraits {
67  enum : size_t { unspecified = KOKKOS_INVALID_INDEX };
68 
69  // Compute the rank of the view from the nonzero dimension arguments.
70  KOKKOS_INLINE_FUNCTION
71  static size_t computeRank(const size_t N0, const size_t N1, const size_t N2,
72  const size_t N3, const size_t N4, const size_t N5,
73  const size_t N6, const size_t /* N7 */) {
74  return (
75  (N6 == unspecified && N5 == unspecified && N4 == unspecified &&
76  N3 == unspecified && N2 == unspecified && N1 == unspecified &&
77  N0 == unspecified)
78  ? 0
79  : ((N6 == unspecified && N5 == unspecified && N4 == unspecified &&
80  N3 == unspecified && N2 == unspecified && N1 == unspecified)
81  ? 1
82  : ((N6 == unspecified && N5 == unspecified &&
83  N4 == unspecified && N3 == unspecified &&
84  N2 == unspecified)
85  ? 2
86  : ((N6 == unspecified && N5 == unspecified &&
87  N4 == unspecified && N3 == unspecified)
88  ? 3
89  : ((N6 == unspecified && N5 == unspecified &&
90  N4 == unspecified)
91  ? 4
92  : ((N6 == unspecified &&
93  N5 == unspecified)
94  ? 5
95  : ((N6 == unspecified)
96  ? 6
97  : 7)))))));
98  }
99 
100  // Compute the rank of the view from the nonzero layout arguments.
101  template <typename Layout>
102  KOKKOS_INLINE_FUNCTION static size_t computeRank(const Layout& layout) {
103  return computeRank(layout.dimension[0], layout.dimension[1],
104  layout.dimension[2], layout.dimension[3],
105  layout.dimension[4], layout.dimension[5],
106  layout.dimension[6], layout.dimension[7]);
107  }
108 
109  // Extra overload to match that for specialize types v2
110  template <typename Layout, typename... P>
111  KOKKOS_INLINE_FUNCTION static size_t computeRank(
112  const Kokkos::Impl::ViewCtorProp<P...>& /* prop */,
113  const Layout& layout) {
114  return computeRank(layout);
115  }
116 
117  // Create the layout for the rank-7 view.
118  // Non-strided Layout
119  template <typename Layout>
120  KOKKOS_INLINE_FUNCTION static typename std::enable_if<
121  (std::is_same<Layout, Kokkos::LayoutRight>::value ||
122  std::is_same<Layout, Kokkos::LayoutLeft>::value),
123  Layout>::type
124  createLayout(const Layout& layout) {
125  return Layout(layout.dimension[0] != unspecified ? layout.dimension[0] : 1,
126  layout.dimension[1] != unspecified ? layout.dimension[1] : 1,
127  layout.dimension[2] != unspecified ? layout.dimension[2] : 1,
128  layout.dimension[3] != unspecified ? layout.dimension[3] : 1,
129  layout.dimension[4] != unspecified ? layout.dimension[4] : 1,
130  layout.dimension[5] != unspecified ? layout.dimension[5] : 1,
131  layout.dimension[6] != unspecified ? layout.dimension[6] : 1,
132  layout.dimension[7] != unspecified ? layout.dimension[7] : 1);
133  }
134 
135  // LayoutStride
136  template <typename Layout>
137  KOKKOS_INLINE_FUNCTION static typename std::enable_if<
138  (std::is_same<Layout, Kokkos::LayoutStride>::value), Layout>::type
139  createLayout(const Layout& layout) {
140  return Layout(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] : 1,
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 typename std::enable_if<
161  (std::is_same<typename Traits::array_layout,
162  Kokkos::LayoutRight>::value ||
163  std::is_same<typename Traits::array_layout, Kokkos::LayoutLeft>::value ||
164  std::is_same<typename Traits::array_layout,
165  Kokkos::LayoutStride>::value),
166  typename Traits::array_layout>::type
167  createLayout(const Kokkos::Impl::ViewCtorProp<P...>& /* prop */,
168  const typename Traits::array_layout& layout) {
169  return createLayout(layout);
170  }
171 
172  // Create a view from the given dimension arguments.
173  // This is only necessary because the shmem constructor doesn't take a layout.
174  // NDE shmem View's are not compatible with the added view_alloc value_type
175  // / fad_dim deduction functionality
176  template <typename ViewType, typename ViewArg>
177  static ViewType createView(const ViewArg& arg, const size_t N0,
178  const size_t N1, const size_t N2, const size_t N3,
179  const size_t N4, const size_t N5, const size_t N6,
180  const size_t N7) {
181  return ViewType(arg, N0 != unspecified ? N0 : 1, N1 != unspecified ? N1 : 1,
182  N2 != unspecified ? N2 : 1, N3 != unspecified ? N3 : 1,
183  N4 != unspecified ? N4 : 1, N5 != unspecified ? N5 : 1,
184  N6 != unspecified ? N6 : 1, N7 != unspecified ? N7 : 1);
185  }
186 };
187 
188 // Non-strided Layout
189 template <typename Layout, typename iType>
190 KOKKOS_INLINE_FUNCTION static
191  typename std::enable_if<(std::is_same<Layout, Kokkos::LayoutRight>::value ||
192  std::is_same<Layout, Kokkos::LayoutLeft>::value) &&
193  std::is_integral<iType>::value,
194  Layout>::type
195  reconstructLayout(const Layout& layout, iType dynrank) {
196  return Layout(dynrank > 0 ? layout.dimension[0] : KOKKOS_INVALID_INDEX,
197  dynrank > 1 ? layout.dimension[1] : KOKKOS_INVALID_INDEX,
198  dynrank > 2 ? layout.dimension[2] : KOKKOS_INVALID_INDEX,
199  dynrank > 3 ? layout.dimension[3] : KOKKOS_INVALID_INDEX,
200  dynrank > 4 ? layout.dimension[4] : KOKKOS_INVALID_INDEX,
201  dynrank > 5 ? layout.dimension[5] : KOKKOS_INVALID_INDEX,
202  dynrank > 6 ? layout.dimension[6] : KOKKOS_INVALID_INDEX,
203  dynrank > 7 ? layout.dimension[7] : KOKKOS_INVALID_INDEX);
204 }
205 
206 // LayoutStride
207 template <typename Layout, typename iType>
208 KOKKOS_INLINE_FUNCTION static typename std::enable_if<
209  (std::is_same<Layout, Kokkos::LayoutStride>::value) &&
210  std::is_integral<iType>::value,
211  Layout>::type
212 reconstructLayout(const Layout& layout, iType dynrank) {
213  return Layout(dynrank > 0 ? layout.dimension[0] : KOKKOS_INVALID_INDEX,
214  dynrank > 0 ? layout.stride[0] : (0),
215  dynrank > 1 ? layout.dimension[1] : KOKKOS_INVALID_INDEX,
216  dynrank > 1 ? layout.stride[1] : (0),
217  dynrank > 2 ? layout.dimension[2] : KOKKOS_INVALID_INDEX,
218  dynrank > 2 ? layout.stride[2] : (0),
219  dynrank > 3 ? layout.dimension[3] : KOKKOS_INVALID_INDEX,
220  dynrank > 3 ? layout.stride[3] : (0),
221  dynrank > 4 ? layout.dimension[4] : KOKKOS_INVALID_INDEX,
222  dynrank > 4 ? layout.stride[4] : (0),
223  dynrank > 5 ? layout.dimension[5] : KOKKOS_INVALID_INDEX,
224  dynrank > 5 ? layout.stride[5] : (0),
225  dynrank > 6 ? layout.dimension[6] : KOKKOS_INVALID_INDEX,
226  dynrank > 6 ? layout.stride[6] : (0),
227  dynrank > 7 ? layout.dimension[7] : KOKKOS_INVALID_INDEX,
228  dynrank > 7 ? layout.stride[7] : (0));
229 }
230 
232 // Enhanced debug checking - most infrastructure matches that of functions in
233 // Kokkos_ViewMapping; additional checks for extra arguments beyond rank are 0
234 template <unsigned, typename iType0, class MapType>
235 KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
236  const iType0&, const MapType&) {
237  return true;
238 }
239 
240 template <unsigned R, typename iType0, class MapType, typename iType1,
241  class... Args>
242 KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
243  const iType0& rank, const MapType& map, const iType1& i, Args... args) {
244  if (static_cast<iType0>(R) < rank) {
245  return (size_t(i) < map.extent(R)) &&
246  dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
247  } else if (i != 0) {
248  KOKKOS_IMPL_DO_NOT_USE_PRINTF(
249  "DynRankView Debug Bounds Checking Error: at rank %u\n Extra "
250  "arguments beyond the rank must be zero \n",
251  R);
252  return (false) &&
253  dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
254  } else {
255  return (true) &&
256  dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
257  }
258 }
259 
260 template <unsigned, class MapType>
261 inline void dyn_rank_view_error_operator_bounds(char*, int, const MapType&) {}
262 
263 template <unsigned R, class MapType, class iType, class... Args>
264 inline void dyn_rank_view_error_operator_bounds(char* buf, int len,
265  const MapType& map,
266  const iType& i, Args... args) {
267  const int n = snprintf(
268  buf, len, " %ld < %ld %c", static_cast<unsigned long>(i),
269  static_cast<unsigned long>(map.extent(R)), (sizeof...(Args) ? ',' : ')'));
270  dyn_rank_view_error_operator_bounds<R + 1>(buf + n, len - n, map, args...);
271 }
272 
273 // op_rank = rank of the operator version that was called
274 template <typename MemorySpace, typename iType0, typename iType1, class MapType,
275  class... Args>
276 KOKKOS_INLINE_FUNCTION void dyn_rank_view_verify_operator_bounds(
277  const iType0& op_rank, const iType1& rank,
278  const Kokkos::Impl::SharedAllocationTracker& tracker, const MapType& map,
279  Args... args) {
280  if (static_cast<iType0>(rank) > op_rank) {
281  Kokkos::abort(
282  "DynRankView Bounds Checking Error: Need at least rank arguments to "
283  "the operator()");
284  }
285 
286  if (!dyn_rank_view_verify_operator_bounds<0>(rank, map, args...)) {
287 #if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
288  enum { LEN = 1024 };
289  char buffer[LEN];
290  const std::string label = tracker.template get_label<MemorySpace>();
291  int n = snprintf(buffer, LEN, "DynRankView bounds error of view %s (",
292  label.c_str());
293  dyn_rank_view_error_operator_bounds<0>(buffer + n, LEN - n, map, args...);
294  Kokkos::Impl::throw_runtime_exception(std::string(buffer));
295 #else
296  (void)tracker;
297  Kokkos::abort("DynRankView bounds error");
298 #endif
299  }
300 }
301 
304 
305 } // namespace Impl
306 
307 namespace Impl {
308 
309 template <class DstTraits, class SrcTraits>
310 class ViewMapping<
311  DstTraits, SrcTraits,
312  typename std::enable_if<
313  (std::is_same<typename DstTraits::memory_space,
314  typename SrcTraits::memory_space>::value &&
315  std::is_same<typename DstTraits::specialize, void>::value &&
316  std::is_same<typename SrcTraits::specialize, void>::value &&
317  (std::is_same<typename DstTraits::array_layout,
318  typename SrcTraits::array_layout>::value ||
319  ((std::is_same<typename DstTraits::array_layout,
320  Kokkos::LayoutLeft>::value ||
321  std::is_same<typename DstTraits::array_layout,
322  Kokkos::LayoutRight>::value ||
323  std::is_same<typename DstTraits::array_layout,
324  Kokkos::LayoutStride>::value) &&
325  (std::is_same<typename SrcTraits::array_layout,
326  Kokkos::LayoutLeft>::value ||
327  std::is_same<typename SrcTraits::array_layout,
328  Kokkos::LayoutRight>::value ||
329  std::is_same<typename SrcTraits::array_layout,
330  Kokkos::LayoutStride>::value)))),
331  Kokkos::Impl::ViewToDynRankViewTag>::type> {
332  private:
333  enum {
334  is_assignable_value_type =
335  std::is_same<typename DstTraits::value_type,
336  typename SrcTraits::value_type>::value ||
337  std::is_same<typename DstTraits::value_type,
338  typename SrcTraits::const_value_type>::value
339  };
340 
341  enum {
342  is_assignable_layout =
343  std::is_same<typename DstTraits::array_layout,
344  typename SrcTraits::array_layout>::value ||
345  std::is_same<typename DstTraits::array_layout,
346  Kokkos::LayoutStride>::value
347  };
348 
349  public:
350  enum { is_assignable = is_assignable_value_type && is_assignable_layout };
351 
352  using DstType = ViewMapping<DstTraits, typename DstTraits::specialize>;
353  using SrcType = ViewMapping<SrcTraits, typename SrcTraits::specialize>;
354 
355  template <typename DT, typename... DP, typename ST, typename... SP>
356  KOKKOS_INLINE_FUNCTION static void assign(
357  Kokkos::DynRankView<DT, DP...>& dst, const Kokkos::View<ST, SP...>& src) {
358  static_assert(
359  is_assignable_value_type,
360  "View assignment must have same value type or const = non-const");
361 
362  static_assert(
363  is_assignable_layout,
364  "View assignment must have compatible layout or have rank <= 1");
365 
366  // Removed dimension checks...
367 
368  using dst_offset_type = typename DstType::offset_type;
369  dst.m_map.m_impl_offset = dst_offset_type(
370  std::integral_constant<unsigned, 0>(),
371  src.layout()); // Check this for integer input1 for padding, etc
372  dst.m_map.m_impl_handle = Kokkos::Impl::ViewDataHandle<DstTraits>::assign(
373  src.m_map.m_impl_handle, src.m_track.m_tracker);
374  dst.m_track.assign(src.m_track.m_tracker, DstTraits::is_managed);
375  dst.m_rank = src.Rank;
376  }
377 };
378 
379 } // namespace Impl
380 
381 /* \class DynRankView
382  * \brief Container that creates a Kokkos view with rank determined at runtime.
383  * Essentially this is a rank 7 view
384  *
385  * Changes from View
386  * 1. The rank of the DynRankView is returned by the method rank()
387  * 2. Max rank of a DynRankView is 7
388  * 3. subview called with 'subview(...)' or 'subdynrankview(...)' (backward
389  * compatibility)
390  * 4. Every subview is returned with LayoutStride
391  * 5. Copy and Copy-Assign View to DynRankView
392  * 6. deep_copy between Views and DynRankViews
393  * 7. rank( view ); returns the rank of View or DynRankView
394  *
395  */
396 
397 template <class>
398 struct is_dyn_rank_view : public std::false_type {};
399 
400 template <class D, class... P>
401 struct is_dyn_rank_view<Kokkos::DynRankView<D, P...> > : public std::true_type {
402 };
403 
404 template <typename DataType, class... Properties>
405 class DynRankView : public ViewTraits<DataType, Properties...> {
406  static_assert(!std::is_array<DataType>::value &&
407  !std::is_pointer<DataType>::value,
408  "Cannot template DynRankView with array or pointer datatype - "
409  "must be pod");
410 
411  private:
412  template <class, class...>
413  friend class DynRankView;
414  template <class, class...>
415  friend class Kokkos::Impl::ViewMapping;
416 
417  public:
418  using drvtraits = ViewTraits<DataType, Properties...>;
419 
420  using view_type = View<DataType*******, Properties...>;
421 
422  using traits = ViewTraits<DataType*******, Properties...>;
423 
424  private:
425  using map_type =
426  Kokkos::Impl::ViewMapping<traits, typename traits::specialize>;
427  using track_type = Kokkos::Impl::SharedAllocationTracker;
428 
429  track_type m_track;
430  map_type m_map;
431  unsigned m_rank;
432 
433  public:
434  KOKKOS_INLINE_FUNCTION
435  view_type& DownCast() const { return (view_type&)(*this); }
436  KOKKOS_INLINE_FUNCTION
437  const view_type& ConstDownCast() const { return (const view_type&)(*this); }
438 
439  // Types below - at least the HostMirror requires the value_type, NOT the rank
440  // 7 data_type of the traits
441 
443  using array_type = DynRankView<
444  typename drvtraits::scalar_array_type, typename drvtraits::array_layout,
445  typename drvtraits::device_type, typename drvtraits::memory_traits>;
446 
448  using const_type = DynRankView<
449  typename drvtraits::const_data_type, typename drvtraits::array_layout,
450  typename drvtraits::device_type, typename drvtraits::memory_traits>;
451 
453  using non_const_type = DynRankView<
454  typename drvtraits::non_const_data_type, typename drvtraits::array_layout,
455  typename drvtraits::device_type, typename drvtraits::memory_traits>;
456 
458  using HostMirror = DynRankView<typename drvtraits::non_const_data_type,
459  typename drvtraits::array_layout,
460  typename drvtraits::host_mirror_space>;
461 
462  //----------------------------------------
463  // Domain rank and extents
464 
465  // enum { Rank = map_type::Rank }; //Will be dyn rank of 7 always, keep the
466  // enum?
467 
468  template <typename iType>
469  KOKKOS_INLINE_FUNCTION constexpr
470  typename std::enable_if<std::is_integral<iType>::value, size_t>::type
471  extent(const iType& r) const {
472  return m_map.extent(r);
473  }
474 
475  template <typename iType>
476  KOKKOS_INLINE_FUNCTION constexpr
477  typename std::enable_if<std::is_integral<iType>::value, int>::type
478  extent_int(const iType& r) const {
479  return static_cast<int>(m_map.extent(r));
480  }
481 
482  KOKKOS_INLINE_FUNCTION constexpr typename traits::array_layout layout()
483  const {
484  return m_map.layout();
485  }
486 
487  //----------------------------------------
488  /* Deprecate all 'dimension' functions in favor of
489  * ISO/C++ vocabulary 'extent'.
490  */
491 
492  KOKKOS_INLINE_FUNCTION constexpr size_t size() const {
493  return m_map.extent(0) * m_map.extent(1) * m_map.extent(2) *
494  m_map.extent(3) * m_map.extent(4) * m_map.extent(5) *
495  m_map.extent(6) * m_map.extent(7);
496  }
497 
498  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const {
499  return m_map.stride_0();
500  }
501  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const {
502  return m_map.stride_1();
503  }
504  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const {
505  return m_map.stride_2();
506  }
507  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const {
508  return m_map.stride_3();
509  }
510  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const {
511  return m_map.stride_4();
512  }
513  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const {
514  return m_map.stride_5();
515  }
516  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const {
517  return m_map.stride_6();
518  }
519  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const {
520  return m_map.stride_7();
521  }
522 
523  template <typename iType>
524  KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
525  m_map.stride(s);
526  }
527 
528  //----------------------------------------
529  // Range span is the span which contains all members.
530 
531  using reference_type = typename map_type::reference_type;
532  using pointer_type = typename map_type::pointer_type;
533 
534  enum {
535  reference_type_is_lvalue_reference =
536  std::is_lvalue_reference<reference_type>::value
537  };
538 
539  KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return m_map.span(); }
540  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
541  return m_map.span_is_contiguous();
542  }
543  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
544  return m_map.data();
545  }
546  KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
547  return (m_map.data() != nullptr);
548  }
549 
550  //----------------------------------------
551  // Allow specializations to query their specialized map
552  KOKKOS_INLINE_FUNCTION
553  const Kokkos::Impl::ViewMapping<traits, typename traits::specialize>&
554  impl_map() const {
555  return m_map;
556  }
557 
558  //----------------------------------------
559 
560  private:
561  enum {
562  is_layout_left =
563  std::is_same<typename traits::array_layout, Kokkos::LayoutLeft>::value,
564 
565  is_layout_right =
566  std::is_same<typename traits::array_layout, Kokkos::LayoutRight>::value,
567 
568  is_layout_stride = std::is_same<typename traits::array_layout,
569  Kokkos::LayoutStride>::value,
570 
571  is_default_map = std::is_same<typename traits::specialize, void>::value &&
572  (is_layout_left || is_layout_right || is_layout_stride)
573  };
574 
575 // Bounds checking macros
576 #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
577 
578 // rank of the calling operator - included as first argument in ARG
579 #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(ARG) \
580  Kokkos::Impl::verify_space<Kokkos::Impl::ActiveExecutionMemorySpace, \
581  typename traits::memory_space>::check(); \
582  Kokkos::Impl::dyn_rank_view_verify_operator_bounds< \
583  typename traits::memory_space> \
584  ARG;
585 
586 #else
587 
588 #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(ARG) \
589  Kokkos::Impl::verify_space<Kokkos::Impl::ActiveExecutionMemorySpace, \
590  typename traits::memory_space>::check();
591 
592 #endif
593 
594  public:
595  KOKKOS_INLINE_FUNCTION
596  constexpr unsigned rank() const { return m_rank; }
597 
598  // operators ()
599  // Rank 0
600  KOKKOS_INLINE_FUNCTION
601  reference_type operator()() const {
602  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((0, this->rank(), m_track, m_map))
603  return impl_map().reference();
604  // return m_map.reference(0,0,0,0,0,0,0);
605  }
606 
607  // Rank 1
608  // This assumes a contiguous underlying memory (i.e. no padding, no
609  // striding...)
610  template <typename iType>
611  KOKKOS_INLINE_FUNCTION typename std::enable_if<
612  std::is_same<typename drvtraits::value_type,
613  typename drvtraits::scalar_array_type>::value &&
614  std::is_integral<iType>::value,
615  reference_type>::type
616  operator[](const iType& i0) const {
617  // Phalanx is violating this, since they use the operator to access ALL
618  // elements in the allocation KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (1 ,
619  // this->rank(), m_track, m_map) )
620  return data()[i0];
621  }
622 
623  // This assumes a contiguous underlying memory (i.e. no padding, no
624  // striding... AND a Trilinos/Sacado scalar type )
625  template <typename iType>
626  KOKKOS_INLINE_FUNCTION typename std::enable_if<
627  !std::is_same<typename drvtraits::value_type,
628  typename drvtraits::scalar_array_type>::value &&
629  std::is_integral<iType>::value,
630  reference_type>::type
631  operator[](const iType& i0) const {
632  // auto map = impl_map();
633  const size_t dim_scalar = m_map.dimension_scalar();
634  const size_t bytes = this->span() / dim_scalar;
635 
636  using tmp_view_type = Kokkos::View<
637  DataType*, typename traits::array_layout, typename traits::device_type,
638  Kokkos::MemoryTraits<traits::memory_traits::is_unmanaged |
639  traits::memory_traits::is_random_access |
640  traits::memory_traits::is_atomic> >;
641  tmp_view_type rankone_view(this->data(), bytes, dim_scalar);
642  return rankone_view(i0);
643  }
644 
645  // Rank 1 parenthesis
646  template <typename iType>
647  KOKKOS_INLINE_FUNCTION typename std::enable_if<
648  (std::is_same<typename traits::specialize, void>::value &&
649  std::is_integral<iType>::value),
650  reference_type>::type
651  operator()(const iType& i0) const {
652  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
653  return m_map.reference(i0);
654  }
655 
656  template <typename iType>
657  KOKKOS_INLINE_FUNCTION typename std::enable_if<
658  !(std::is_same<typename traits::specialize, void>::value &&
659  std::is_integral<iType>::value),
660  reference_type>::type
661  operator()(const iType& i0) const {
662  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
663  return m_map.reference(i0, 0, 0, 0, 0, 0, 0);
664  }
665 
666  // Rank 2
667  template <typename iType0, typename iType1>
668  KOKKOS_INLINE_FUNCTION typename std::enable_if<
669  (std::is_same<typename traits::specialize, void>::value &&
670  std::is_integral<iType0>::value && std::is_integral<iType1>::value),
671  reference_type>::type
672  operator()(const iType0& i0, const iType1& i1) const {
673  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
674  return m_map.reference(i0, i1);
675  }
676 
677  template <typename iType0, typename iType1>
678  KOKKOS_INLINE_FUNCTION typename std::enable_if<
679  !(std::is_same<typename drvtraits::specialize, void>::value &&
680  std::is_integral<iType0>::value),
681  reference_type>::type
682  operator()(const iType0& i0, const iType1& i1) const {
683  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
684  return m_map.reference(i0, i1, 0, 0, 0, 0, 0);
685  }
686 
687  // Rank 3
688  template <typename iType0, typename iType1, typename iType2>
689  KOKKOS_INLINE_FUNCTION typename std::enable_if<
690  (std::is_same<typename traits::specialize, void>::value &&
691  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
692  std::is_integral<iType2>::value),
693  reference_type>::type
694  operator()(const iType0& i0, const iType1& i1, const iType2& i2) const {
695  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
696  (3, this->rank(), m_track, m_map, i0, i1, i2))
697  return m_map.reference(i0, i1, i2);
698  }
699 
700  template <typename iType0, typename iType1, typename iType2>
701  KOKKOS_INLINE_FUNCTION typename std::enable_if<
702  !(std::is_same<typename drvtraits::specialize, void>::value &&
703  std::is_integral<iType0>::value),
704  reference_type>::type
705  operator()(const iType0& i0, const iType1& i1, const iType2& i2) const {
706  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
707  (3, this->rank(), m_track, m_map, i0, i1, i2))
708  return m_map.reference(i0, i1, i2, 0, 0, 0, 0);
709  }
710 
711  // Rank 4
712  template <typename iType0, typename iType1, typename iType2, typename iType3>
713  KOKKOS_INLINE_FUNCTION typename std::enable_if<
714  (std::is_same<typename traits::specialize, void>::value &&
715  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
716  std::is_integral<iType2>::value && std::is_integral<iType3>::value),
717  reference_type>::type
718  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
719  const iType3& i3) const {
720  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
721  (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
722  return m_map.reference(i0, i1, i2, i3);
723  }
724 
725  template <typename iType0, typename iType1, typename iType2, typename iType3>
726  KOKKOS_INLINE_FUNCTION typename std::enable_if<
727  !(std::is_same<typename drvtraits::specialize, void>::value &&
728  std::is_integral<iType0>::value),
729  reference_type>::type
730  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
731  const iType3& i3) const {
732  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
733  (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
734  return m_map.reference(i0, i1, i2, i3, 0, 0, 0);
735  }
736 
737  // Rank 5
738  template <typename iType0, typename iType1, typename iType2, typename iType3,
739  typename iType4>
740  KOKKOS_INLINE_FUNCTION typename std::enable_if<
741  (std::is_same<typename traits::specialize, void>::value &&
742  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
743  std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
744  std::is_integral<iType4>::value),
745  reference_type>::type
746  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
747  const iType3& i3, const iType4& i4) const {
748  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
749  (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
750  return m_map.reference(i0, i1, i2, i3, i4);
751  }
752 
753  template <typename iType0, typename iType1, typename iType2, typename iType3,
754  typename iType4>
755  KOKKOS_INLINE_FUNCTION typename std::enable_if<
756  !(std::is_same<typename drvtraits::specialize, void>::value &&
757  std::is_integral<iType0>::value),
758  reference_type>::type
759  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
760  const iType3& i3, const iType4& i4) const {
761  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
762  (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
763  return m_map.reference(i0, i1, i2, i3, i4, 0, 0);
764  }
765 
766  // Rank 6
767  template <typename iType0, typename iType1, typename iType2, typename iType3,
768  typename iType4, typename iType5>
769  KOKKOS_INLINE_FUNCTION typename std::enable_if<
770  (std::is_same<typename traits::specialize, void>::value &&
771  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
772  std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
773  std::is_integral<iType4>::value && std::is_integral<iType5>::value),
774  reference_type>::type
775  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
776  const iType3& i3, const iType4& i4, const iType5& i5) const {
777  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
778  (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
779  return m_map.reference(i0, i1, i2, i3, i4, i5);
780  }
781 
782  template <typename iType0, typename iType1, typename iType2, typename iType3,
783  typename iType4, typename iType5>
784  KOKKOS_INLINE_FUNCTION typename std::enable_if<
785  !(std::is_same<typename drvtraits::specialize, void>::value &&
786  std::is_integral<iType0>::value),
787  reference_type>::type
788  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
789  const iType3& i3, const iType4& i4, const iType5& i5) const {
790  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
791  (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
792  return m_map.reference(i0, i1, i2, i3, i4, i5, 0);
793  }
794 
795  // Rank 7
796  template <typename iType0, typename iType1, typename iType2, typename iType3,
797  typename iType4, typename iType5, typename iType6>
798  KOKKOS_INLINE_FUNCTION typename std::enable_if<
799  (std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
800  std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
801  std::is_integral<iType4>::value && std::is_integral<iType5>::value &&
802  std::is_integral<iType6>::value),
803  reference_type>::type
804  operator()(const iType0& i0, const iType1& i1, const iType2& i2,
805  const iType3& i3, const iType4& i4, const iType5& i5,
806  const iType6& i6) const {
807  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
808  (7, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5, i6))
809  return m_map.reference(i0, i1, i2, i3, i4, i5, i6);
810  }
811 
812  // Rank 0
813  KOKKOS_INLINE_FUNCTION
814  reference_type access() const {
815  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((0, this->rank(), m_track, m_map))
816  return impl_map().reference();
817  // return m_map.reference(0,0,0,0,0,0,0);
818  }
819 
820  // Rank 1
821  // Rank 1 parenthesis
822  template <typename iType>
823  KOKKOS_INLINE_FUNCTION typename std::enable_if<
824  (std::is_same<typename traits::specialize, void>::value &&
825  std::is_integral<iType>::value),
826  reference_type>::type
827  access(const iType& i0) const {
828  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
829  return m_map.reference(i0);
830  }
831 
832  template <typename iType>
833  KOKKOS_INLINE_FUNCTION typename std::enable_if<
834  !(std::is_same<typename traits::specialize, void>::value &&
835  std::is_integral<iType>::value),
836  reference_type>::type
837  access(const iType& i0) const {
838  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
839  return m_map.reference(i0, 0, 0, 0, 0, 0, 0);
840  }
841 
842  // Rank 2
843  template <typename iType0, typename iType1>
844  KOKKOS_INLINE_FUNCTION typename std::enable_if<
845  (std::is_same<typename traits::specialize, void>::value &&
846  std::is_integral<iType0>::value && std::is_integral<iType1>::value),
847  reference_type>::type
848  access(const iType0& i0, const iType1& i1) const {
849  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
850  return m_map.reference(i0, i1);
851  }
852 
853  template <typename iType0, typename iType1>
854  KOKKOS_INLINE_FUNCTION typename std::enable_if<
855  !(std::is_same<typename drvtraits::specialize, void>::value &&
856  std::is_integral<iType0>::value),
857  reference_type>::type
858  access(const iType0& i0, const iType1& i1) const {
859  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
860  return m_map.reference(i0, i1, 0, 0, 0, 0, 0);
861  }
862 
863  // Rank 3
864  template <typename iType0, typename iType1, typename iType2>
865  KOKKOS_INLINE_FUNCTION typename std::enable_if<
866  (std::is_same<typename traits::specialize, void>::value &&
867  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
868  std::is_integral<iType2>::value),
869  reference_type>::type
870  access(const iType0& i0, const iType1& i1, const iType2& i2) const {
871  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
872  (3, this->rank(), m_track, m_map, i0, i1, i2))
873  return m_map.reference(i0, i1, i2);
874  }
875 
876  template <typename iType0, typename iType1, typename iType2>
877  KOKKOS_INLINE_FUNCTION typename std::enable_if<
878  !(std::is_same<typename drvtraits::specialize, void>::value &&
879  std::is_integral<iType0>::value),
880  reference_type>::type
881  access(const iType0& i0, const iType1& i1, const iType2& i2) const {
882  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
883  (3, this->rank(), m_track, m_map, i0, i1, i2))
884  return m_map.reference(i0, i1, i2, 0, 0, 0, 0);
885  }
886 
887  // Rank 4
888  template <typename iType0, typename iType1, typename iType2, typename iType3>
889  KOKKOS_INLINE_FUNCTION typename std::enable_if<
890  (std::is_same<typename traits::specialize, void>::value &&
891  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
892  std::is_integral<iType2>::value && std::is_integral<iType3>::value),
893  reference_type>::type
894  access(const iType0& i0, const iType1& i1, const iType2& i2,
895  const iType3& i3) const {
896  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
897  (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
898  return m_map.reference(i0, i1, i2, i3);
899  }
900 
901  template <typename iType0, typename iType1, typename iType2, typename iType3>
902  KOKKOS_INLINE_FUNCTION typename std::enable_if<
903  !(std::is_same<typename drvtraits::specialize, void>::value &&
904  std::is_integral<iType0>::value),
905  reference_type>::type
906  access(const iType0& i0, const iType1& i1, const iType2& i2,
907  const iType3& i3) const {
908  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
909  (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
910  return m_map.reference(i0, i1, i2, i3, 0, 0, 0);
911  }
912 
913  // Rank 5
914  template <typename iType0, typename iType1, typename iType2, typename iType3,
915  typename iType4>
916  KOKKOS_INLINE_FUNCTION typename std::enable_if<
917  (std::is_same<typename traits::specialize, void>::value &&
918  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
919  std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
920  std::is_integral<iType4>::value),
921  reference_type>::type
922  access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
923  const iType4& i4) const {
924  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
925  (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
926  return m_map.reference(i0, i1, i2, i3, i4);
927  }
928 
929  template <typename iType0, typename iType1, typename iType2, typename iType3,
930  typename iType4>
931  KOKKOS_INLINE_FUNCTION typename std::enable_if<
932  !(std::is_same<typename drvtraits::specialize, void>::value &&
933  std::is_integral<iType0>::value),
934  reference_type>::type
935  access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
936  const iType4& i4) const {
937  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
938  (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
939  return m_map.reference(i0, i1, i2, i3, i4, 0, 0);
940  }
941 
942  // Rank 6
943  template <typename iType0, typename iType1, typename iType2, typename iType3,
944  typename iType4, typename iType5>
945  KOKKOS_INLINE_FUNCTION typename std::enable_if<
946  (std::is_same<typename traits::specialize, void>::value &&
947  std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
948  std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
949  std::is_integral<iType4>::value && std::is_integral<iType5>::value),
950  reference_type>::type
951  access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
952  const iType4& i4, const iType5& i5) const {
953  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
954  (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
955  return m_map.reference(i0, i1, i2, i3, i4, i5);
956  }
957 
958  template <typename iType0, typename iType1, typename iType2, typename iType3,
959  typename iType4, typename iType5>
960  KOKKOS_INLINE_FUNCTION typename std::enable_if<
961  !(std::is_same<typename drvtraits::specialize, void>::value &&
962  std::is_integral<iType0>::value),
963  reference_type>::type
964  access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
965  const iType4& i4, const iType5& i5) const {
966  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
967  (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
968  return m_map.reference(i0, i1, i2, i3, i4, i5, 0);
969  }
970 
971  // Rank 7
972  template <typename iType0, typename iType1, typename iType2, typename iType3,
973  typename iType4, typename iType5, typename iType6>
974  KOKKOS_INLINE_FUNCTION typename std::enable_if<
975  (std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
976  std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
977  std::is_integral<iType4>::value && std::is_integral<iType5>::value &&
978  std::is_integral<iType6>::value),
979  reference_type>::type
980  access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
981  const iType4& i4, const iType5& i5, const iType6& i6) const {
982  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
983  (7, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5, i6))
984  return m_map.reference(i0, i1, i2, i3, i4, i5, i6);
985  }
986 
987 #undef KOKKOS_IMPL_VIEW_OPERATOR_VERIFY
988 
989  //----------------------------------------
990  // Standard constructor, destructor, and assignment operators...
991 
992  KOKKOS_DEFAULTED_FUNCTION
993  ~DynRankView() = default;
994 
995  KOKKOS_INLINE_FUNCTION
996  DynRankView() : m_track(), m_map(), m_rank() {} // Default ctor
997 
998  KOKKOS_INLINE_FUNCTION
999  DynRankView(const DynRankView& rhs)
1000  : m_track(rhs.m_track), m_map(rhs.m_map), m_rank(rhs.m_rank) {}
1001 
1002  KOKKOS_INLINE_FUNCTION
1003  DynRankView(DynRankView&& rhs)
1004  : m_track(rhs.m_track), m_map(rhs.m_map), m_rank(rhs.m_rank) {}
1005 
1006  KOKKOS_INLINE_FUNCTION
1007  DynRankView& operator=(const DynRankView& rhs) {
1008  m_track = rhs.m_track;
1009  m_map = rhs.m_map;
1010  m_rank = rhs.m_rank;
1011  return *this;
1012  }
1013 
1014  KOKKOS_INLINE_FUNCTION
1015  DynRankView& operator=(DynRankView&& rhs) {
1016  m_track = rhs.m_track;
1017  m_map = rhs.m_map;
1018  m_rank = rhs.m_rank;
1019  return *this;
1020  }
1021 
1022  //----------------------------------------
1023  // Compatible view copy constructor and assignment
1024  // may assign unmanaged from managed.
1025  template <class RT, class... RP>
1026  KOKKOS_INLINE_FUNCTION DynRankView(const DynRankView<RT, RP...>& rhs)
1027  : m_track(rhs.m_track, traits::is_managed), m_map(), m_rank(rhs.m_rank) {
1028  using SrcTraits = typename DynRankView<RT, RP...>::traits;
1029  using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1030  typename traits::specialize>;
1031  static_assert(Mapping::is_assignable,
1032  "Incompatible DynRankView copy construction");
1033  Mapping::assign(m_map, rhs.m_map, rhs.m_track);
1034  }
1035 
1036  template <class RT, class... RP>
1037  KOKKOS_INLINE_FUNCTION DynRankView& operator=(
1038  const DynRankView<RT, RP...>& rhs) {
1039  using SrcTraits = typename DynRankView<RT, RP...>::traits;
1040  using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1041  typename traits::specialize>;
1042  static_assert(Mapping::is_assignable,
1043  "Incompatible DynRankView copy construction");
1044  Mapping::assign(m_map, rhs.m_map, rhs.m_track);
1045  m_track.assign(rhs.m_track, traits::is_managed);
1046  m_rank = rhs.rank();
1047  return *this;
1048  }
1049 
1050  // Copy/Assign View to DynRankView
1051  template <class RT, class... RP>
1052  KOKKOS_INLINE_FUNCTION DynRankView(const View<RT, RP...>& rhs)
1053  : m_track(), m_map(), m_rank(rhs.Rank) {
1054  using SrcTraits = typename View<RT, RP...>::traits;
1055  using Mapping =
1056  Kokkos::Impl::ViewMapping<traits, SrcTraits,
1058  static_assert(Mapping::is_assignable,
1059  "Incompatible View to DynRankView copy construction");
1060  Mapping::assign(*this, rhs);
1061  }
1062 
1063  template <class RT, class... RP>
1064  KOKKOS_INLINE_FUNCTION DynRankView& operator=(const View<RT, RP...>& rhs) {
1065  using SrcTraits = typename View<RT, RP...>::traits;
1066  using Mapping =
1067  Kokkos::Impl::ViewMapping<traits, SrcTraits,
1069  static_assert(Mapping::is_assignable,
1070  "Incompatible View to DynRankView copy assignment");
1071  Mapping::assign(*this, rhs);
1072  return *this;
1073  }
1074 
1075  //----------------------------------------
1076  // Allocation tracking properties
1077 
1078  KOKKOS_INLINE_FUNCTION
1079  int use_count() const { return m_track.use_count(); }
1080 
1081  inline const std::string label() const {
1082  return m_track.template get_label<typename traits::memory_space>();
1083  }
1084 
1085  //----------------------------------------
1086  // Allocation according to allocation properties and array layout
1087  // unused arg_layout dimensions must be set to KOKKOS_INVALID_INDEX so that
1088  // rank deduction can properly take place
1089  template <class... P>
1090  explicit inline DynRankView(
1091  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1092  typename std::enable_if<!Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1093  typename traits::array_layout>::type const&
1094  arg_layout)
1095  : m_track(),
1096  m_map(),
1097  m_rank(Impl::DynRankDimTraits<typename traits::specialize>::
1098  template computeRank<typename traits::array_layout, P...>(
1099  arg_prop, arg_layout)) {
1100  // Append layout and spaces if not input
1101  using alloc_prop_input = Kokkos::Impl::ViewCtorProp<P...>;
1102 
1103  // use 'std::integral_constant<unsigned,I>' for non-types
1104  // to avoid duplicate class error.
1105  using alloc_prop = Kokkos::Impl::ViewCtorProp<
1106  P...,
1107  typename std::conditional<alloc_prop_input::has_label,
1108  std::integral_constant<unsigned, 0>,
1109  typename std::string>::type,
1110  typename std::conditional<
1111  alloc_prop_input::has_memory_space,
1112  std::integral_constant<unsigned, 1>,
1113  typename traits::device_type::memory_space>::type,
1114  typename std::conditional<
1115  alloc_prop_input::has_execution_space,
1116  std::integral_constant<unsigned, 2>,
1117  typename traits::device_type::execution_space>::type>;
1118 
1119  static_assert(traits::is_managed,
1120  "View allocation constructor requires managed memory");
1121 
1122  if (alloc_prop::initialize &&
1123  !alloc_prop::execution_space::impl_is_initialized()) {
1124  // If initializing view data then
1125  // the execution space must be initialized.
1126  Kokkos::Impl::throw_runtime_exception(
1127  "Constructing DynRankView and initializing data with uninitialized "
1128  "execution space");
1129  }
1130 
1131  // Copy the input allocation properties with possibly defaulted properties
1132  alloc_prop prop_copy(arg_prop);
1133 
1134 //------------------------------------------------------------
1135 #if defined(KOKKOS_ENABLE_CUDA)
1136  // If allocating in CudaUVMSpace must fence before and after
1137  // the allocation to protect against possible concurrent access
1138  // on the CPU and the GPU.
1139  // Fence using the trait's executon space (which will be Kokkos::Cuda)
1140  // to avoid incomplete type errors from usng Kokkos::Cuda directly.
1141  if (std::is_same<Kokkos::CudaUVMSpace,
1142  typename traits::device_type::memory_space>::value) {
1143  typename traits::device_type::memory_space::execution_space().fence();
1144  }
1145 #endif
1146  //------------------------------------------------------------
1147 
1148  Kokkos::Impl::SharedAllocationRecord<>* record = m_map.allocate_shared(
1149  prop_copy,
1150  Impl::DynRankDimTraits<typename traits::specialize>::
1151  template createLayout<traits, P...>(arg_prop, arg_layout));
1152 
1153 //------------------------------------------------------------
1154 #if defined(KOKKOS_ENABLE_CUDA)
1155  if (std::is_same<Kokkos::CudaUVMSpace,
1156  typename traits::device_type::memory_space>::value) {
1157  typename traits::device_type::memory_space::execution_space().fence();
1158  }
1159 #endif
1160  //------------------------------------------------------------
1161 
1162  // Setup and initialization complete, start tracking
1163  m_track.assign_allocated_record_to_uninitialized(record);
1164  }
1165 
1166  // Wrappers
1167  template <class... P>
1168  explicit KOKKOS_INLINE_FUNCTION DynRankView(
1169  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1170  typename std::enable_if<Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1171  typename traits::array_layout>::type const&
1172  arg_layout)
1173  : m_track() // No memory tracking
1174  ,
1175  m_map(arg_prop,
1176  Impl::DynRankDimTraits<typename traits::specialize>::
1177  template createLayout<traits, P...>(arg_prop, arg_layout)),
1178  m_rank(Impl::DynRankDimTraits<typename traits::specialize>::
1179  template computeRank<typename traits::array_layout, P...>(
1180  arg_prop, arg_layout)) {
1181  static_assert(
1182  std::is_same<pointer_type,
1183  typename Impl::ViewCtorProp<P...>::pointer_type>::value,
1184  "Constructing DynRankView to wrap user memory must supply matching "
1185  "pointer type");
1186  }
1187 
1188  //----------------------------------------
1189  // Constructor(s)
1190 
1191  // Simple dimension-only layout
1192  template <class... P>
1193  explicit inline DynRankView(
1194  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1195  typename std::enable_if<!Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1196  size_t>::type const arg_N0 = KOKKOS_INVALID_INDEX,
1197  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1198  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1199  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1200  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1201  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1202  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1203  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1204  : DynRankView(arg_prop, typename traits::array_layout(
1205  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1206  arg_N5, arg_N6, arg_N7)) {}
1207 
1208  template <class... P>
1209  explicit KOKKOS_INLINE_FUNCTION DynRankView(
1210  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1211  typename std::enable_if<Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1212  size_t>::type const arg_N0 = KOKKOS_INVALID_INDEX,
1213  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1214  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1215  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1216  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1217  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1218  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1219  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1220  : DynRankView(arg_prop, typename traits::array_layout(
1221  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1222  arg_N5, arg_N6, arg_N7)) {}
1223 
1224  // Allocate with label and layout
1225  template <typename Label>
1226  explicit inline DynRankView(
1227  const Label& arg_label,
1228  typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value,
1229  typename traits::array_layout>::type const&
1230  arg_layout)
1231  : DynRankView(Kokkos::Impl::ViewCtorProp<std::string>(arg_label),
1232  arg_layout) {}
1233 
1234  // Allocate label and layout, must disambiguate from subview constructor
1235  template <typename Label>
1236  explicit inline DynRankView(
1237  const Label& arg_label,
1238  typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value,
1239  const size_t>::type arg_N0 = KOKKOS_INVALID_INDEX,
1240  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1241  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1242  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1243  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1244  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1245  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1246  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1247  : DynRankView(
1248  Kokkos::Impl::ViewCtorProp<std::string>(arg_label),
1249  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1250  arg_N4, arg_N5, arg_N6, arg_N7)) {}
1251 
1252  //----------------------------------------
1253  // Memory span required to wrap these dimensions.
1254  static constexpr size_t required_allocation_size(
1255  const size_t arg_N0 = 0, const size_t arg_N1 = 0, const size_t arg_N2 = 0,
1256  const size_t arg_N3 = 0, const size_t arg_N4 = 0, const size_t arg_N5 = 0,
1257  const size_t arg_N6 = 0, const size_t arg_N7 = 0) {
1258  return map_type::memory_span(typename traits::array_layout(
1259  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1260  }
1261 
1262  explicit KOKKOS_INLINE_FUNCTION DynRankView(
1263  pointer_type arg_ptr, const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1264  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1265  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1266  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1267  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1268  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1269  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1270  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1271  : DynRankView(Kokkos::Impl::ViewCtorProp<pointer_type>(arg_ptr), arg_N0,
1272  arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7) {}
1273 
1274  explicit KOKKOS_INLINE_FUNCTION DynRankView(
1275  pointer_type arg_ptr, typename traits::array_layout& arg_layout)
1276  : DynRankView(Kokkos::Impl::ViewCtorProp<pointer_type>(arg_ptr),
1277  arg_layout) {}
1278 
1279  //----------------------------------------
1280  // Shared scratch memory constructor
1281 
1282  static inline size_t shmem_size(const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1283  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1284  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1285  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1286  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1287  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1288  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1289  const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
1290  const size_t num_passed_args =
1291  (arg_N0 != KOKKOS_INVALID_INDEX) + (arg_N1 != KOKKOS_INVALID_INDEX) +
1292  (arg_N2 != KOKKOS_INVALID_INDEX) + (arg_N3 != KOKKOS_INVALID_INDEX) +
1293  (arg_N4 != KOKKOS_INVALID_INDEX) + (arg_N5 != KOKKOS_INVALID_INDEX) +
1294  (arg_N6 != KOKKOS_INVALID_INDEX) + (arg_N7 != KOKKOS_INVALID_INDEX);
1295 
1296  if (std::is_same<typename traits::specialize, void>::value &&
1297  num_passed_args != traits::rank_dynamic) {
1298  Kokkos::abort(
1299  "Kokkos::View::shmem_size() rank_dynamic != number of arguments.\n");
1300  }
1301  {}
1302 
1303  return map_type::memory_span(typename traits::array_layout(
1304  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1305  }
1306 
1307  explicit KOKKOS_INLINE_FUNCTION DynRankView(
1308  const typename traits::execution_space::scratch_memory_space& arg_space,
1309  const typename traits::array_layout& arg_layout)
1310  : DynRankView(
1311  Kokkos::Impl::ViewCtorProp<pointer_type>(
1312  reinterpret_cast<pointer_type>(
1313  arg_space.get_shmem(map_type::memory_span(
1314  Impl::DynRankDimTraits<typename traits::specialize>::
1315  createLayout(arg_layout) // is this correct?
1316  )))),
1317  arg_layout) {}
1318 
1319  explicit KOKKOS_INLINE_FUNCTION DynRankView(
1320  const typename traits::execution_space::scratch_memory_space& arg_space,
1321  const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1322  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1323  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1324  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1325  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1326  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1327  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1328  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1329 
1330  : DynRankView(
1331  Kokkos::Impl::ViewCtorProp<pointer_type>(
1332  reinterpret_cast<pointer_type>(
1333  arg_space.get_shmem(map_type::memory_span(
1334  Impl::DynRankDimTraits<typename traits::specialize>::
1335  createLayout(typename traits::array_layout(
1336  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
1337  arg_N6, arg_N7)))))),
1338  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1339  arg_N4, arg_N5, arg_N6, arg_N7)) {}
1340 };
1341 
1342 template <typename D, class... P>
1343 KOKKOS_INLINE_FUNCTION constexpr unsigned rank(
1344  const DynRankView<D, P...>& DRV) {
1345  return DRV.rank();
1346 } // needed for transition to common constexpr method in view and dynrankview
1347  // to return rank
1348 
1349 //----------------------------------------------------------------------------
1350 // Subview mapping.
1351 // Deduce destination view type from source view traits and subview arguments
1352 
1353 namespace Impl {
1354 
1355 struct DynRankSubviewTag {};
1356 
1357 } // namespace Impl
1358 
1359 namespace Impl {
1360 
1361 template <class SrcTraits, class... Args>
1362 class ViewMapping<
1363  typename std::enable_if<
1364  (std::is_same<typename SrcTraits::specialize, void>::value &&
1365  (std::is_same<typename SrcTraits::array_layout,
1366  Kokkos::LayoutLeft>::value ||
1367  std::is_same<typename SrcTraits::array_layout,
1368  Kokkos::LayoutRight>::value ||
1369  std::is_same<typename SrcTraits::array_layout,
1370  Kokkos::LayoutStride>::value)),
1371  Kokkos::Impl::DynRankSubviewTag>::type,
1372  SrcTraits, Args...> {
1373  private:
1374  enum {
1375  RZ = false,
1376  R0 = bool(is_integral_extent<0, Args...>::value),
1377  R1 = bool(is_integral_extent<1, Args...>::value),
1378  R2 = bool(is_integral_extent<2, Args...>::value),
1379  R3 = bool(is_integral_extent<3, Args...>::value),
1380  R4 = bool(is_integral_extent<4, Args...>::value),
1381  R5 = bool(is_integral_extent<5, Args...>::value),
1382  R6 = bool(is_integral_extent<6, Args...>::value)
1383  };
1384 
1385  enum {
1386  rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3) +
1387  unsigned(R4) + unsigned(R5) + unsigned(R6)
1388  };
1389 
1390  using array_layout = Kokkos::LayoutStride;
1391 
1392  using value_type = typename SrcTraits::value_type;
1393 
1394  using data_type = value_type*******;
1395 
1396  public:
1397  using traits_type = Kokkos::ViewTraits<data_type, array_layout,
1398  typename SrcTraits::device_type,
1399  typename SrcTraits::memory_traits>;
1400 
1401  using type =
1402  Kokkos::View<data_type, array_layout, typename SrcTraits::device_type,
1403  typename SrcTraits::memory_traits>;
1404 
1405  template <class MemoryTraits>
1406  struct apply {
1407  static_assert(Kokkos::Impl::is_memory_traits<MemoryTraits>::value, "");
1408 
1409  using traits_type =
1410  Kokkos::ViewTraits<data_type, array_layout,
1411  typename SrcTraits::device_type, MemoryTraits>;
1412 
1413  using type = Kokkos::View<data_type, array_layout,
1414  typename SrcTraits::device_type, MemoryTraits>;
1415  };
1416 
1417  using dimension = typename SrcTraits::dimension;
1418 
1419  template <class Arg0 = int, class Arg1 = int, class Arg2 = int,
1420  class Arg3 = int, class Arg4 = int, class Arg5 = int,
1421  class Arg6 = int>
1422  struct ExtentGenerator {
1423  KOKKOS_INLINE_FUNCTION
1424  static SubviewExtents<7, rank> generator(
1425  const dimension& dim, Arg0 arg0 = Arg0(), Arg1 arg1 = Arg1(),
1426  Arg2 arg2 = Arg2(), Arg3 arg3 = Arg3(), Arg4 arg4 = Arg4(),
1427  Arg5 arg5 = Arg5(), Arg6 arg6 = Arg6()) {
1428  return SubviewExtents<7, rank>(dim, arg0, arg1, arg2, arg3, arg4, arg5,
1429  arg6);
1430  }
1431  };
1432 
1433  using ret_type = Kokkos::DynRankView<value_type, array_layout,
1434  typename SrcTraits::device_type,
1435  typename SrcTraits::memory_traits>;
1436 
1437  template <typename T, class... P>
1438  KOKKOS_INLINE_FUNCTION static ret_type subview(
1439  const unsigned src_rank, Kokkos::DynRankView<T, P...> const& src,
1440  Args... args) {
1441  using DstType = ViewMapping<traits_type, typename traits_type::specialize>;
1442 
1443  using DstDimType = typename std::conditional<
1444  (rank == 0), ViewDimension<>,
1445  typename std::conditional<
1446  (rank == 1), ViewDimension<0>,
1447  typename std::conditional<
1448  (rank == 2), ViewDimension<0, 0>,
1449  typename std::conditional<
1450  (rank == 3), ViewDimension<0, 0, 0>,
1451  typename std::conditional<
1452  (rank == 4), ViewDimension<0, 0, 0, 0>,
1453  typename std::conditional<
1454  (rank == 5), ViewDimension<0, 0, 0, 0, 0>,
1455  typename std::conditional<
1456  (rank == 6), ViewDimension<0, 0, 0, 0, 0, 0>,
1457  ViewDimension<0, 0, 0, 0, 0, 0, 0> >::type>::
1458  type>::type>::type>::type>::type>::type;
1459 
1460  using dst_offset_type = ViewOffset<DstDimType, Kokkos::LayoutStride>;
1461  using dst_handle_type = typename DstType::handle_type;
1462 
1463  ret_type dst;
1464 
1465  const SubviewExtents<7, rank> extents = ExtentGenerator<Args...>::generator(
1466  src.m_map.m_impl_offset.m_dim, args...);
1467 
1468  dst_offset_type tempdst(src.m_map.m_impl_offset, extents);
1469 
1470  dst.m_track = src.m_track;
1471 
1472  dst.m_map.m_impl_offset.m_dim.N0 = tempdst.m_dim.N0;
1473  dst.m_map.m_impl_offset.m_dim.N1 = tempdst.m_dim.N1;
1474  dst.m_map.m_impl_offset.m_dim.N2 = tempdst.m_dim.N2;
1475  dst.m_map.m_impl_offset.m_dim.N3 = tempdst.m_dim.N3;
1476  dst.m_map.m_impl_offset.m_dim.N4 = tempdst.m_dim.N4;
1477  dst.m_map.m_impl_offset.m_dim.N5 = tempdst.m_dim.N5;
1478  dst.m_map.m_impl_offset.m_dim.N6 = tempdst.m_dim.N6;
1479 
1480  dst.m_map.m_impl_offset.m_stride.S0 = tempdst.m_stride.S0;
1481  dst.m_map.m_impl_offset.m_stride.S1 = tempdst.m_stride.S1;
1482  dst.m_map.m_impl_offset.m_stride.S2 = tempdst.m_stride.S2;
1483  dst.m_map.m_impl_offset.m_stride.S3 = tempdst.m_stride.S3;
1484  dst.m_map.m_impl_offset.m_stride.S4 = tempdst.m_stride.S4;
1485  dst.m_map.m_impl_offset.m_stride.S5 = tempdst.m_stride.S5;
1486  dst.m_map.m_impl_offset.m_stride.S6 = tempdst.m_stride.S6;
1487 
1488  dst.m_map.m_impl_handle =
1489  dst_handle_type(src.m_map.m_impl_handle +
1490  src.m_map.m_impl_offset(
1491  extents.domain_offset(0), extents.domain_offset(1),
1492  extents.domain_offset(2), extents.domain_offset(3),
1493  extents.domain_offset(4), extents.domain_offset(5),
1494  extents.domain_offset(6)));
1495 
1496  dst.m_rank =
1497  (src_rank > 0 ? unsigned(R0) : 0) + (src_rank > 1 ? unsigned(R1) : 0) +
1498  (src_rank > 2 ? unsigned(R2) : 0) + (src_rank > 3 ? unsigned(R3) : 0) +
1499  (src_rank > 4 ? unsigned(R4) : 0) + (src_rank > 5 ? unsigned(R5) : 0) +
1500  (src_rank > 6 ? unsigned(R6) : 0);
1501 
1502  return dst;
1503  }
1504 };
1505 
1506 } // namespace Impl
1507 
1508 template <class V, class... Args>
1509 using Subdynrankview =
1510  typename Kokkos::Impl::ViewMapping<Kokkos::Impl::DynRankSubviewTag, V,
1511  Args...>::ret_type;
1512 
1513 template <class D, class... P, class... Args>
1514 KOKKOS_INLINE_FUNCTION Subdynrankview<ViewTraits<D*******, P...>, Args...>
1515 subdynrankview(const Kokkos::DynRankView<D, P...>& src, Args... args) {
1516  if (src.rank() > sizeof...(Args)) // allow sizeof...(Args) >= src.rank(),
1517  // ignore the remaining args
1518  {
1519  Kokkos::abort(
1520  "subdynrankview: num of args must be >= rank of the source "
1521  "DynRankView");
1522  }
1523 
1524  using metafcn =
1525  Kokkos::Impl::ViewMapping<Kokkos::Impl::DynRankSubviewTag,
1526  Kokkos::ViewTraits<D*******, P...>, Args...>;
1527 
1528  return metafcn::subview(src.rank(), src, args...);
1529 }
1530 
1531 // Wrapper to allow subview function name
1532 template <class D, class... P, class... Args>
1533 KOKKOS_INLINE_FUNCTION Subdynrankview<ViewTraits<D*******, P...>, Args...>
1534 subview(const Kokkos::DynRankView<D, P...>& src, Args... args) {
1535  return subdynrankview(src, args...);
1536 }
1537 
1538 } // namespace Kokkos
1539 
1540 namespace Kokkos {
1541 
1542 // overload == and !=
1543 template <class LT, class... LP, class RT, class... RP>
1544 KOKKOS_INLINE_FUNCTION bool operator==(const DynRankView<LT, LP...>& lhs,
1545  const DynRankView<RT, RP...>& rhs) {
1546  // Same data, layout, dimensions
1547  using lhs_traits = ViewTraits<LT, LP...>;
1548  using rhs_traits = ViewTraits<RT, RP...>;
1549 
1550  return std::is_same<typename lhs_traits::const_value_type,
1551  typename rhs_traits::const_value_type>::value &&
1552  std::is_same<typename lhs_traits::array_layout,
1553  typename rhs_traits::array_layout>::value &&
1554  std::is_same<typename lhs_traits::memory_space,
1555  typename rhs_traits::memory_space>::value &&
1556  lhs.rank() == rhs.rank() && lhs.data() == rhs.data() &&
1557  lhs.span() == rhs.span() && lhs.extent(0) == rhs.extent(0) &&
1558  lhs.extent(1) == rhs.extent(1) && lhs.extent(2) == rhs.extent(2) &&
1559  lhs.extent(3) == rhs.extent(3) && lhs.extent(4) == rhs.extent(4) &&
1560  lhs.extent(5) == rhs.extent(5) && lhs.extent(6) == rhs.extent(6) &&
1561  lhs.extent(7) == rhs.extent(7);
1562 }
1563 
1564 template <class LT, class... LP, class RT, class... RP>
1565 KOKKOS_INLINE_FUNCTION bool operator!=(const DynRankView<LT, LP...>& lhs,
1566  const DynRankView<RT, RP...>& rhs) {
1567  return !(operator==(lhs, rhs));
1568 }
1569 
1570 } // namespace Kokkos
1571 
1572 //----------------------------------------------------------------------------
1573 //----------------------------------------------------------------------------
1574 namespace Kokkos {
1575 namespace Impl {
1576 
1577 template <class OutputView, typename Enable = void>
1578 struct DynRankViewFill {
1579  using const_value_type = typename OutputView::traits::const_value_type;
1580 
1581  const OutputView output;
1582  const_value_type input;
1583 
1584  KOKKOS_INLINE_FUNCTION
1585  void operator()(const size_t i0) const {
1586  const size_t n1 = output.extent(1);
1587  const size_t n2 = output.extent(2);
1588  const size_t n3 = output.extent(3);
1589  const size_t n4 = output.extent(4);
1590  const size_t n5 = output.extent(5);
1591  const size_t n6 = output.extent(6);
1592 
1593  for (size_t i1 = 0; i1 < n1; ++i1) {
1594  for (size_t i2 = 0; i2 < n2; ++i2) {
1595  for (size_t i3 = 0; i3 < n3; ++i3) {
1596  for (size_t i4 = 0; i4 < n4; ++i4) {
1597  for (size_t i5 = 0; i5 < n5; ++i5) {
1598  for (size_t i6 = 0; i6 < n6; ++i6) {
1599  output.access(i0, i1, i2, i3, i4, i5, i6) = input;
1600  }
1601  }
1602  }
1603  }
1604  }
1605  }
1606  }
1607 
1608  DynRankViewFill(const OutputView& arg_out, const_value_type& arg_in)
1609  : output(arg_out), input(arg_in) {
1610  using execution_space = typename OutputView::execution_space;
1611  using Policy = Kokkos::RangePolicy<execution_space>;
1612 
1613  Kokkos::parallel_for("Kokkos::DynRankViewFill", Policy(0, output.extent(0)),
1614  *this);
1615  }
1616 };
1617 
1618 template <class OutputView>
1619 struct DynRankViewFill<OutputView,
1620  typename std::enable_if<OutputView::Rank == 0>::type> {
1621  DynRankViewFill(const OutputView& dst,
1622  const typename OutputView::const_value_type& src) {
1623  Kokkos::Impl::DeepCopy<typename OutputView::memory_space,
1625  dst.data(), &src, sizeof(typename OutputView::const_value_type));
1626  }
1627 };
1628 
1629 template <class OutputView, class InputView,
1630  class ExecSpace = typename OutputView::execution_space>
1631 struct DynRankViewRemap {
1632  const OutputView output;
1633  const InputView input;
1634  const size_t n0;
1635  const size_t n1;
1636  const size_t n2;
1637  const size_t n3;
1638  const size_t n4;
1639  const size_t n5;
1640  const size_t n6;
1641  const size_t n7;
1642 
1643  DynRankViewRemap(const OutputView& arg_out, const InputView& arg_in)
1644  : output(arg_out),
1645  input(arg_in),
1646  n0(std::min((size_t)arg_out.extent(0), (size_t)arg_in.extent(0))),
1647  n1(std::min((size_t)arg_out.extent(1), (size_t)arg_in.extent(1))),
1648  n2(std::min((size_t)arg_out.extent(2), (size_t)arg_in.extent(2))),
1649  n3(std::min((size_t)arg_out.extent(3), (size_t)arg_in.extent(3))),
1650  n4(std::min((size_t)arg_out.extent(4), (size_t)arg_in.extent(4))),
1651  n5(std::min((size_t)arg_out.extent(5), (size_t)arg_in.extent(5))),
1652  n6(std::min((size_t)arg_out.extent(6), (size_t)arg_in.extent(6))),
1653  n7(std::min((size_t)arg_out.extent(7), (size_t)arg_in.extent(7))) {
1654  using Policy = Kokkos::RangePolicy<ExecSpace>;
1655 
1656  Kokkos::parallel_for("Kokkos::DynRankViewRemap", Policy(0, n0), *this);
1657  }
1658 
1659  KOKKOS_INLINE_FUNCTION
1660  void operator()(const size_t i0) const {
1661  for (size_t i1 = 0; i1 < n1; ++i1) {
1662  for (size_t i2 = 0; i2 < n2; ++i2) {
1663  for (size_t i3 = 0; i3 < n3; ++i3) {
1664  for (size_t i4 = 0; i4 < n4; ++i4) {
1665  for (size_t i5 = 0; i5 < n5; ++i5) {
1666  for (size_t i6 = 0; i6 < n6; ++i6) {
1667  output.access(i0, i1, i2, i3, i4, i5, i6) =
1668  input.access(i0, i1, i2, i3, i4, i5, i6);
1669  }
1670  }
1671  }
1672  }
1673  }
1674  }
1675  }
1676 };
1677 
1678 } /* namespace Impl */
1679 } /* namespace Kokkos */
1680 
1681 namespace Kokkos {
1682 
1684 template <class DT, class... DP>
1685 inline void deep_copy(
1686  const DynRankView<DT, DP...>& dst,
1687  typename ViewTraits<DT, DP...>::const_value_type& value,
1688  typename std::enable_if<std::is_same<
1689  typename ViewTraits<DT, DP...>::specialize, void>::value>::type* =
1690  nullptr) {
1691  static_assert(
1692  std::is_same<typename ViewTraits<DT, DP...>::non_const_value_type,
1693  typename ViewTraits<DT, DP...>::value_type>::value,
1694  "deep_copy requires non-const type");
1695 
1696  Kokkos::fence();
1697  Kokkos::Impl::DynRankViewFill<DynRankView<DT, DP...> >(dst, value);
1698  Kokkos::fence();
1699 }
1700 
1702 template <class ST, class... SP>
1703 inline void deep_copy(
1704  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
1705  const DynRankView<ST, SP...>& src,
1706  typename std::enable_if<std::is_same<
1707  typename ViewTraits<ST, SP...>::specialize, void>::value>::type* = 0) {
1708  if (src.rank() != 0) {
1709  Kokkos::abort("");
1710  }
1711 
1712  using src_traits = ViewTraits<ST, SP...>;
1713  using src_memory_space = typename src_traits::memory_space;
1714  Kokkos::fence();
1715  Kokkos::Impl::DeepCopy<HostSpace, src_memory_space>(&dst, src.data(),
1716  sizeof(ST));
1717  Kokkos::fence();
1718 }
1719 
1720 //----------------------------------------------------------------------------
1724 template <class DstType, class SrcType>
1725 inline void deep_copy(
1726  const DstType& dst, const SrcType& src,
1727  typename std::enable_if<
1728  (std::is_same<typename DstType::traits::specialize, void>::value &&
1729  std::is_same<typename SrcType::traits::specialize, void>::value &&
1730  (Kokkos::is_dyn_rank_view<DstType>::value ||
1731  Kokkos::is_dyn_rank_view<SrcType>::value))>::type* = nullptr) {
1732  static_assert(
1733  std::is_same<typename DstType::traits::value_type,
1734  typename DstType::traits::non_const_value_type>::value,
1735  "deep_copy requires non-const destination type");
1736 
1737  using dst_type = DstType;
1738  using src_type = SrcType;
1739 
1740  using dst_execution_space = typename dst_type::execution_space;
1741  using src_execution_space = typename src_type::execution_space;
1742  using dst_memory_space = typename dst_type::memory_space;
1743  using src_memory_space = typename src_type::memory_space;
1744 
1745  enum {
1746  DstExecCanAccessSrc =
1747  Kokkos::Impl::SpaceAccessibility<dst_execution_space,
1748  src_memory_space>::accessible
1749  };
1750 
1751  enum {
1752  SrcExecCanAccessDst =
1753  Kokkos::Impl::SpaceAccessibility<src_execution_space,
1754  dst_memory_space>::accessible
1755  };
1756 
1757  if ((void*)dst.data() != (void*)src.data()) {
1758  // Concern: If overlapping views then a parallel copy will be erroneous.
1759  // ...
1760 
1761  // If same type, equal layout, equal dimensions, equal span, and contiguous
1762  // memory then can byte-wise copy
1763  if (rank(src) == 0 && rank(dst) == 0) {
1764  using value_type = typename dst_type::value_type;
1765  Kokkos::fence();
1766  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1767  dst.data(), src.data(), sizeof(value_type));
1768  Kokkos::fence();
1769  } else if (std::is_same<
1770  typename DstType::traits::value_type,
1771  typename SrcType::traits::non_const_value_type>::value &&
1772  ((std::is_same<typename DstType::traits::array_layout,
1773  typename SrcType::traits::array_layout>::value &&
1774  (std::is_same<typename DstType::traits::array_layout,
1775  typename Kokkos::LayoutLeft>::value ||
1776  std::is_same<typename DstType::traits::array_layout,
1777  typename Kokkos::LayoutRight>::value)) ||
1778  (rank(dst) == 1 && rank(src) == 1)) &&
1779  dst.span_is_contiguous() && src.span_is_contiguous() &&
1780  dst.span() == src.span() && dst.extent(0) == src.extent(0) &&
1781 
1782  dst.extent(1) == src.extent(1) &&
1783  dst.extent(2) == src.extent(2) &&
1784  dst.extent(3) == src.extent(3) &&
1785  dst.extent(4) == src.extent(4) &&
1786  dst.extent(5) == src.extent(5) &&
1787  dst.extent(6) == src.extent(6) &&
1788  dst.extent(7) == src.extent(7)) {
1789  const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
1790  Kokkos::fence();
1791  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1792  dst.data(), src.data(), nbytes);
1793  Kokkos::fence();
1794  } else if (std::is_same<
1795  typename DstType::traits::value_type,
1796  typename SrcType::traits::non_const_value_type>::value &&
1797  ((std::is_same<typename DstType::traits::array_layout,
1798  typename SrcType::traits::array_layout>::value &&
1799  std::is_same<typename DstType::traits::array_layout,
1800  typename Kokkos::LayoutStride>::value) ||
1801  (rank(dst) == 1 && rank(src) == 1)) &&
1802  dst.span_is_contiguous() && src.span_is_contiguous() &&
1803  dst.span() == src.span() && dst.extent(0) == src.extent(0) &&
1804  dst.extent(1) == src.extent(1) &&
1805  dst.extent(2) == src.extent(2) &&
1806  dst.extent(3) == src.extent(3) &&
1807  dst.extent(4) == src.extent(4) &&
1808  dst.extent(5) == src.extent(5) &&
1809  dst.extent(6) == src.extent(6) &&
1810  dst.extent(7) == src.extent(7) &&
1811  dst.stride_0() == src.stride_0() &&
1812  dst.stride_1() == src.stride_1() &&
1813  dst.stride_2() == src.stride_2() &&
1814  dst.stride_3() == src.stride_3() &&
1815  dst.stride_4() == src.stride_4() &&
1816  dst.stride_5() == src.stride_5() &&
1817  dst.stride_6() == src.stride_6() &&
1818  dst.stride_7() == src.stride_7()) {
1819  const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
1820  Kokkos::fence();
1821  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1822  dst.data(), src.data(), nbytes);
1823  Kokkos::fence();
1824  } else if (DstExecCanAccessSrc) {
1825  // Copying data between views in accessible memory spaces and either
1826  // non-contiguous or incompatible shape.
1827  Kokkos::fence();
1828  Kokkos::Impl::DynRankViewRemap<dst_type, src_type>(dst, src);
1829  Kokkos::fence();
1830  } else if (SrcExecCanAccessDst) {
1831  // Copying data between views in accessible memory spaces and either
1832  // non-contiguous or incompatible shape.
1833  Kokkos::fence();
1834  Kokkos::Impl::DynRankViewRemap<dst_type, src_type, src_execution_space>(
1835  dst, src);
1836  Kokkos::fence();
1837  } else {
1838  Kokkos::Impl::throw_runtime_exception(
1839  "deep_copy given views that would require a temporary allocation");
1840  }
1841  } else {
1842  Kokkos::fence();
1843  }
1844 }
1845 
1846 } // namespace Kokkos
1847 
1848 //----------------------------------------------------------------------------
1849 //----------------------------------------------------------------------------
1850 
1851 namespace Kokkos {
1852 namespace Impl {
1853 
1854 // Deduce Mirror Types
1855 template <class Space, class T, class... P>
1856 struct MirrorDRViewType {
1857  // The incoming view_type
1858  using src_view_type = typename Kokkos::DynRankView<T, P...>;
1859  // The memory space for the mirror view
1860  using memory_space = typename Space::memory_space;
1861  // Check whether it is the same memory space
1862  enum {
1863  is_same_memspace =
1864  std::is_same<memory_space, typename src_view_type::memory_space>::value
1865  };
1866  // The array_layout
1867  using array_layout = typename src_view_type::array_layout;
1868  // The data type (we probably want it non-const since otherwise we can't even
1869  // deep_copy to it.
1870  using data_type = typename src_view_type::non_const_data_type;
1871  // The destination view type if it is not the same memory space
1872  using dest_view_type = Kokkos::DynRankView<data_type, array_layout, Space>;
1873  // If it is the same memory_space return the existsing view_type
1874  // This will also keep the unmanaged trait if necessary
1875  using view_type = typename std::conditional<is_same_memspace, src_view_type,
1876  dest_view_type>::type;
1877 };
1878 
1879 template <class Space, class T, class... P>
1880 struct MirrorDRVType {
1881  // The incoming view_type
1882  using src_view_type = typename Kokkos::DynRankView<T, P...>;
1883  // The memory space for the mirror view
1884  using memory_space = typename Space::memory_space;
1885  // Check whether it is the same memory space
1886  enum {
1887  is_same_memspace =
1888  std::is_same<memory_space, typename src_view_type::memory_space>::value
1889  };
1890  // The array_layout
1891  using array_layout = typename src_view_type::array_layout;
1892  // The data type (we probably want it non-const since otherwise we can't even
1893  // deep_copy to it.
1894  using data_type = typename src_view_type::non_const_data_type;
1895  // The destination view type if it is not the same memory space
1896  using view_type = Kokkos::DynRankView<data_type, array_layout, Space>;
1897 };
1898 
1899 } // namespace Impl
1900 
1901 template <class T, class... P>
1902 inline typename DynRankView<T, P...>::HostMirror create_mirror(
1903  const DynRankView<T, P...>& src,
1904  typename std::enable_if<
1905  std::is_same<typename ViewTraits<T, P...>::specialize, void>::value &&
1906  !std::is_same<typename Kokkos::ViewTraits<T, P...>::array_layout,
1907  Kokkos::LayoutStride>::value>::type* = nullptr) {
1908  using src_type = DynRankView<T, P...>;
1909  using dst_type = typename src_type::HostMirror;
1910 
1911  return dst_type(std::string(src.label()).append("_mirror"),
1912  Impl::reconstructLayout(src.layout(), src.rank()));
1913 }
1914 
1915 template <class T, class... P>
1916 inline typename DynRankView<T, P...>::HostMirror create_mirror(
1917  const DynRankView<T, P...>& src,
1918  typename std::enable_if<
1919  std::is_same<typename ViewTraits<T, P...>::specialize, void>::value &&
1920  std::is_same<typename Kokkos::ViewTraits<T, P...>::array_layout,
1921  Kokkos::LayoutStride>::value>::type* = 0) {
1922  using src_type = DynRankView<T, P...>;
1923  using dst_type = typename src_type::HostMirror;
1924 
1925  return dst_type(std::string(src.label()).append("_mirror"),
1926  Impl::reconstructLayout(src.layout(), src.rank()));
1927 }
1928 
1929 // Create a mirror in a new space (specialization for different space)
1930 template <class Space, class T, class... P>
1931 typename Impl::MirrorDRVType<Space, T, P...>::view_type create_mirror(
1932  const Space&, const Kokkos::DynRankView<T, P...>& src,
1933  typename std::enable_if<std::is_same<
1934  typename ViewTraits<T, P...>::specialize, void>::value>::type* =
1935  nullptr) {
1936  return typename Impl::MirrorDRVType<Space, T, P...>::view_type(
1937  src.label(), Impl::reconstructLayout(src.layout(), src.rank()));
1938 }
1939 
1940 template <class T, class... P>
1941 inline typename DynRankView<T, P...>::HostMirror create_mirror_view(
1942  const DynRankView<T, P...>& src,
1943  typename std::enable_if<
1944  (std::is_same<
1945  typename DynRankView<T, P...>::memory_space,
1946  typename DynRankView<T, P...>::HostMirror::memory_space>::value &&
1947  std::is_same<typename DynRankView<T, P...>::data_type,
1948  typename DynRankView<T, P...>::HostMirror::data_type>::
1949  value)>::type* = nullptr) {
1950  return src;
1951 }
1952 
1953 template <class T, class... P>
1954 inline typename DynRankView<T, P...>::HostMirror create_mirror_view(
1955  const DynRankView<T, P...>& src,
1956  typename std::enable_if<
1957  !(std::is_same<
1958  typename DynRankView<T, P...>::memory_space,
1959  typename DynRankView<T, P...>::HostMirror::memory_space>::value &&
1960  std::is_same<typename DynRankView<T, P...>::data_type,
1961  typename DynRankView<T, P...>::HostMirror::data_type>::
1962  value)>::type* = nullptr) {
1963  return Kokkos::create_mirror(src);
1964 }
1965 
1966 // Create a mirror view in a new space (specialization for same space)
1967 template <class Space, class T, class... P>
1968 typename Impl::MirrorDRViewType<Space, T, P...>::view_type create_mirror_view(
1969  const Space&, const Kokkos::DynRankView<T, P...>& src,
1970  typename std::enable_if<
1971  Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
1972  nullptr) {
1973  return src;
1974 }
1975 
1976 // Create a mirror view in a new space (specialization for different space)
1977 template <class Space, class T, class... P>
1978 typename Impl::MirrorDRViewType<Space, T, P...>::view_type create_mirror_view(
1979  const Space&, const Kokkos::DynRankView<T, P...>& src,
1980  typename std::enable_if<
1981  !Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
1982  nullptr) {
1983  return typename Impl::MirrorDRViewType<Space, T, P...>::view_type(
1984  src.label(), Impl::reconstructLayout(src.layout(), src.rank()));
1985 }
1986 
1987 // Create a mirror view and deep_copy in a new space (specialization for same
1988 // space)
1989 template <class Space, class T, class... P>
1990 typename Impl::MirrorDRViewType<Space, T, P...>::view_type
1991 create_mirror_view_and_copy(
1992  const Space&, const Kokkos::DynRankView<T, P...>& src,
1993  std::string const& name = "",
1994  typename std::enable_if<
1995  Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
1996  nullptr) {
1997  (void)name;
1998  return src;
1999 }
2000 
2001 // Create a mirror view and deep_copy in a new space (specialization for
2002 // different space)
2003 template <class Space, class T, class... P>
2004 typename Impl::MirrorDRViewType<Space, T, P...>::view_type
2005 create_mirror_view_and_copy(
2006  const Space&, const Kokkos::DynRankView<T, P...>& src,
2007  std::string const& name = "",
2008  typename std::enable_if<
2009  !Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
2010  nullptr) {
2011  using Mirror = typename Impl::MirrorDRViewType<Space, T, P...>::view_type;
2012  std::string label = name.empty() ? src.label() : name;
2013  auto mirror = Mirror(view_alloc(WithoutInitializing, label),
2014  Impl::reconstructLayout(src.layout(), src.rank()));
2015  deep_copy(mirror, src);
2016  return mirror;
2017 }
2018 
2019 } // namespace Kokkos
2020 
2021 //----------------------------------------------------------------------------
2022 //----------------------------------------------------------------------------
2023 
2024 namespace Kokkos {
2027 template <class T, class... P>
2028 inline void resize(DynRankView<T, P...>& v,
2029  const size_t n0 = KOKKOS_INVALID_INDEX,
2030  const size_t n1 = KOKKOS_INVALID_INDEX,
2031  const size_t n2 = KOKKOS_INVALID_INDEX,
2032  const size_t n3 = KOKKOS_INVALID_INDEX,
2033  const size_t n4 = KOKKOS_INVALID_INDEX,
2034  const size_t n5 = KOKKOS_INVALID_INDEX,
2035  const size_t n6 = KOKKOS_INVALID_INDEX,
2036  const size_t n7 = KOKKOS_INVALID_INDEX) {
2037  using drview_type = DynRankView<T, P...>;
2038 
2040  "Can only resize managed views");
2041 
2042  drview_type v_resized(v.label(), n0, n1, n2, n3, n4, n5, n6, n7);
2043 
2044  Kokkos::Impl::DynRankViewRemap<drview_type, drview_type>(v_resized, v);
2045 
2046  v = v_resized;
2047 }
2048 
2051 template <class T, class... P>
2052 inline void realloc(DynRankView<T, P...>& v,
2053  const size_t n0 = KOKKOS_INVALID_INDEX,
2054  const size_t n1 = KOKKOS_INVALID_INDEX,
2055  const size_t n2 = KOKKOS_INVALID_INDEX,
2056  const size_t n3 = KOKKOS_INVALID_INDEX,
2057  const size_t n4 = KOKKOS_INVALID_INDEX,
2058  const size_t n5 = KOKKOS_INVALID_INDEX,
2059  const size_t n6 = KOKKOS_INVALID_INDEX,
2060  const size_t n7 = KOKKOS_INVALID_INDEX) {
2061  using drview_type = DynRankView<T, P...>;
2062 
2064  "Can only realloc managed views");
2065 
2066  const std::string label = v.label();
2067 
2068  v = drview_type(); // Deallocate first, if the only view to allocation
2069  v = drview_type(label, n0, n1, n2, n3, n4, n5, n6, n7);
2070 }
2071 
2072 } // namespace Kokkos
2073 
2074 #endif
View
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Can AccessSpace access MemorySpace ?
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
View to an array of data.
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.
KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(const iType0 &, const MapType &)
Debug bounds-checking routines.
Traits class for accessing attributes of a View.
Definition: dummy.cpp:3