Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
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
34namespace Kokkos {
35
36template <typename DataType, class... Properties>
37class DynRankView; // forward declare
38
39namespace Impl {
40
41template <class T, size_t Rank>
42struct ViewDataTypeFromRank {
43 using type = typename ViewDataTypeFromRank<T, Rank - 1>::type*;
44};
45
46template <class T>
47struct ViewDataTypeFromRank<T, 0> {
48 using type = T;
49};
50
51template <unsigned N, typename T, typename... Args>
52KOKKOS_FUNCTION View<typename ViewDataTypeFromRank<T, N>::type, Args...>
53as_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
58template <typename Specialize>
59struct 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
187template <typename Layout, typename iType>
188KOKKOS_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>
192reconstructLayout(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
204template <typename Layout, typename iType>
205KOKKOS_INLINE_FUNCTION static std::enable_if_t<
206 (std::is_same_v<Layout, Kokkos::LayoutStride>)&&std::is_integral_v<iType>,
207 Layout>
208reconstructLayout(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
230template <unsigned, typename iType0, class MapType>
231KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
232 const iType0&, const MapType&) {
233 return true;
234}
235
236template <unsigned R, typename iType0, class MapType, typename iType1,
237 class... Args>
238KOKKOS_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)) &&
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) &&
250 } else {
251 return (true) &&
253 }
254}
255
256template <unsigned, class MapType>
257inline void dyn_rank_view_error_operator_bounds(char*, int, const MapType&) {}
258
259template <unsigned R, class MapType, class iType, class... Args>
260inline 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
270template <typename MemorySpace, typename iType0, typename iType1, class MapType,
271 class... Args>
272KOKKOS_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
302namespace Impl {
303
304template <class DstTraits, class SrcTraits>
305class 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
394template <class>
395struct is_dyn_rank_view : public std::false_type {};
396
397template <class D, class... P>
398struct is_dyn_rank_view<Kokkos::DynRankView<D, P...>> : public std::true_type {
399};
400
401template <class T>
402inline 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
406template <typename DataType, class... Properties>
407class 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,
810 Kokkos::Impl::ViewToDynRankViewTag>;
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
1030template <typename D, class... P>
1031KOKKOS_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
1040namespace Impl {
1041
1042struct DynRankSubviewTag {};
1043
1044} // namespace Impl
1045
1046template <class V, class... Args>
1047using Subdynrankview =
1048 typename Kokkos::Impl::ViewMapping<Kokkos::Impl::DynRankSubviewTag, V,
1049 Args...>::ret_type;
1050
1051template <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>
1054KOKKOS_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}
1077template <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>
1080KOKKOS_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
1090namespace Kokkos {
1091
1092// overload == and !=
1093template <class LT, class... LP, class RT, class... RP>
1094KOKKOS_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
1114template <class LT, class... LP, class RT, class... RP>
1115KOKKOS_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//----------------------------------------------------------------------------
1124namespace Kokkos {
1125namespace Impl {
1126
1127template <class OutputView, class Enable = void>
1128struct 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
1168template <class OutputView>
1169struct 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,
1173 Kokkos::HostSpace>(
1174 dst.data(), &src, sizeof(typename OutputView::const_value_type));
1175 }
1176};
1177
1178template <class OutputView, class InputView,
1179 class ExecSpace = typename OutputView::execution_space>
1180struct 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
1248namespace Kokkos {
1249
1250namespace 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 */
1255template <unsigned N, typename T, typename... Args>
1256KOKKOS_FUNCTION View<typename ViewDataTypeFromRank<T, N>::type, Args...>
1257as_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
1283template <typename Function, typename... Args>
1284void 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
1310template <class ExecSpace, class DT, class... DP>
1311inline 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
1325template <class DT, class... DP>
1326inline 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
1336template <class ExecSpace, class ST, class... SP>
1337inline 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
1346template <class ST, class... SP>
1347inline 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//----------------------------------------------------------------------------
1361template <class ExecSpace, class DstType, class SrcType>
1362inline 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
1412template <class DstType, class SrcType>
1413inline 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
1468namespace Kokkos {
1469namespace Impl {
1470
1471// Deduce Mirror Types
1472template <class Space, class T, class... P>
1473struct 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
1498namespace Impl {
1499
1500// create a mirror
1501// private interface that accepts arbitrary view constructor args passed by a
1502// view_alloc
1503template <class T, class... P, class... ViewCtorArgs>
1504inline 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
1534template <class T, class... P,
1535 class Enable = std::enable_if_t<
1536 std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1537inline 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
1542template <class T, class... P,
1543 class Enable = std::enable_if_t<
1544 std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1545inline 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
1551template <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>>>
1555inline 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
1562template <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>>>
1566inline 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
1574template <class T, class... P, class... ViewCtorArgs,
1575 typename Enable = std::enable_if_t<
1576 std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1577inline 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
1582namespace Impl {
1583
1584// create a mirror view
1585// private interface that accepts arbitrary view constructor args passed by a
1586// view_alloc
1587template <class T, class... P, class... ViewCtorArgs>
1588inline 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
1624template <class T, class... P>
1625inline 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
1630template <class T, class... P>
1631inline 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
1637template <class Space, class T, class... P,
1638 class Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
1639inline 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
1646template <class Space, class T, class... P,
1647 typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
1648inline 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
1657template <class T, class... P, class... ViewCtorArgs>
1658inline 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
1667template <class... ViewCtorArgs, class T, class... P,
1668 class Enable = std::enable_if_t<
1669 std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1670auto 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
1711template <class Space, class T, class... P>
1712auto 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
1724namespace Kokkos {
1727template <class... ViewCtorArgs, class T, class... P>
1728inline 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
1763template <class T, class... P>
1764inline 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
1776template <class... ViewCtorArgs, class T, class... P>
1777void 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
1790template <class I, class T, class... P>
1791inline 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
1806template <class... ViewCtorArgs, class T, class... P>
1807inline 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
1833template <class T, class... P, class... ViewCtorArgs>
1834inline 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
1847template <class T, class... P>
1848inline 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
1860template <class I, class T, class... P>
1861inline 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
View
ScopeGuard Some user scope issues have been identified with some Kokkos::finalize calls; ScopeGuard a...
KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(const iType0 &, const MapType &)
Debug bounds-checking routines.
Assign compatible default mappings.