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