Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_View.hpp
1//@HEADER
2// ************************************************************************
3//
4// Kokkos v. 4.0
5// Copyright (2022) National Technology & Engineering
6// Solutions of Sandia, LLC (NTESS).
7//
8// Under the terms of Contract DE-NA0003525 with NTESS,
9// the U.S. Government retains certain rights in this software.
10//
11// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12// See https://kokkos.org/LICENSE for license information.
13// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14//
15//@HEADER
16
17#ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18#include <Kokkos_Macros.hpp>
19static_assert(false,
20 "Including non-public Kokkos header files is not allowed.");
21#endif
22#ifndef KOKKOS_VIEW_HPP
23#define KOKKOS_VIEW_HPP
24
25#include <type_traits>
26#include <string>
27#include <algorithm>
28#include <initializer_list>
29
30#include <Kokkos_Core_fwd.hpp>
31#include <Kokkos_HostSpace.hpp>
32#include <Kokkos_MemoryTraits.hpp>
33#include <Kokkos_ExecPolicy.hpp>
34#include <View/Hooks/Kokkos_ViewHooks.hpp>
35
36#include <impl/Kokkos_Tools.hpp>
37
38#ifdef KOKKOS_ENABLE_IMPL_MDSPAN
39#include <View/MDSpan/Kokkos_MDSpan_Extents.hpp>
40#endif
41#include <Kokkos_MinMaxClamp.hpp>
42
43//----------------------------------------------------------------------------
44//----------------------------------------------------------------------------
45
46namespace Kokkos {
47namespace Impl {
48
49template <class DataType>
50struct ViewArrayAnalysis;
51
52template <class DataType, class ArrayLayout,
53 typename ValueType =
54 typename ViewArrayAnalysis<DataType>::non_const_value_type>
55struct ViewDataAnalysis;
56
57template <class, class...>
58class ViewMapping {
59 public:
60 enum : bool { is_assignable_data_type = false };
61 enum : bool { is_assignable = false };
62};
63
64template <typename IntType>
65constexpr KOKKOS_INLINE_FUNCTION std::size_t count_valid_integers(
66 const IntType i0, const IntType i1, const IntType i2, const IntType i3,
67 const IntType i4, const IntType i5, const IntType i6, const IntType i7) {
68 static_assert(std::is_integral<IntType>::value,
69 "count_valid_integers() must have integer arguments.");
70
71 return (i0 != KOKKOS_INVALID_INDEX) + (i1 != KOKKOS_INVALID_INDEX) +
72 (i2 != KOKKOS_INVALID_INDEX) + (i3 != KOKKOS_INVALID_INDEX) +
73 (i4 != KOKKOS_INVALID_INDEX) + (i5 != KOKKOS_INVALID_INDEX) +
74 (i6 != KOKKOS_INVALID_INDEX) + (i7 != KOKKOS_INVALID_INDEX);
75}
76
77KOKKOS_INLINE_FUNCTION
78void runtime_check_rank(const size_t rank, const size_t dyn_rank,
79 const bool is_void_spec, const size_t i0,
80 const size_t i1, const size_t i2, const size_t i3,
81 const size_t i4, const size_t i5, const size_t i6,
82 const size_t i7, const std::string& label) {
83 (void)(label);
84
85 if (is_void_spec) {
86 const size_t num_passed_args =
87 count_valid_integers(i0, i1, i2, i3, i4, i5, i6, i7);
88
89 if (num_passed_args != dyn_rank && num_passed_args != rank) {
90 KOKKOS_IF_ON_HOST(
91 const std::string message =
92 "Constructor for Kokkos View '" + label +
93 "' has mismatched number of arguments. Number of arguments = " +
94 std::to_string(num_passed_args) +
95 " but dynamic rank = " + std::to_string(dyn_rank) + " \n";
96 Kokkos::abort(message.c_str());)
97 KOKKOS_IF_ON_DEVICE(Kokkos::abort("Constructor for Kokkos View has "
98 "mismatched number of arguments.");)
99 }
100 }
101}
102
103} /* namespace Impl */
104} /* namespace Kokkos */
105
106// Class to provide a uniform type
107namespace Kokkos {
108namespace Impl {
109template <class ViewType, int Traits = 0>
110struct ViewUniformType;
111}
112} // namespace Kokkos
113
114//----------------------------------------------------------------------------
115//----------------------------------------------------------------------------
116
117namespace Kokkos {
118
136template <class DataType, class... Properties>
137struct ViewTraits;
138
139template <>
140struct ViewTraits<void> {
141 using execution_space = void;
142 using memory_space = void;
143 using HostMirrorSpace = void;
144 using array_layout = void;
145 using memory_traits = void;
146 using specialize = void;
147 using hooks_policy = void;
148};
149
150template <class... Prop>
151struct ViewTraits<void, void, Prop...> {
152 // Ignore an extraneous 'void'
153 using execution_space = typename ViewTraits<void, Prop...>::execution_space;
154 using memory_space = typename ViewTraits<void, Prop...>::memory_space;
155 using HostMirrorSpace = typename ViewTraits<void, Prop...>::HostMirrorSpace;
156 using array_layout = typename ViewTraits<void, Prop...>::array_layout;
157 using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
158 using specialize = typename ViewTraits<void, Prop...>::specialize;
159 using hooks_policy = typename ViewTraits<void, Prop...>::hooks_policy;
160};
161
162template <class HooksPolicy, class... Prop>
163struct ViewTraits<
164 std::enable_if_t<Kokkos::Experimental::is_hooks_policy<HooksPolicy>::value>,
165 HooksPolicy, Prop...> {
166 using execution_space = typename ViewTraits<void, Prop...>::execution_space;
167 using memory_space = typename ViewTraits<void, Prop...>::memory_space;
168 using HostMirrorSpace = typename ViewTraits<void, Prop...>::HostMirrorSpace;
169 using array_layout = typename ViewTraits<void, Prop...>::array_layout;
170 using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
171 using specialize = typename ViewTraits<void, Prop...>::specialize;
172 using hooks_policy = HooksPolicy;
173};
174
175template <class ArrayLayout, class... Prop>
176struct ViewTraits<std::enable_if_t<Kokkos::is_array_layout<ArrayLayout>::value>,
177 ArrayLayout, Prop...> {
178 // Specify layout, keep subsequent space and memory traits arguments
179
180 using execution_space = typename ViewTraits<void, Prop...>::execution_space;
181 using memory_space = typename ViewTraits<void, Prop...>::memory_space;
182 using HostMirrorSpace = typename ViewTraits<void, Prop...>::HostMirrorSpace;
183 using array_layout = ArrayLayout;
184 using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
185 using specialize = typename ViewTraits<void, Prop...>::specialize;
186 using hooks_policy = typename ViewTraits<void, Prop...>::hooks_policy;
187};
188
189template <class Space, class... Prop>
190struct ViewTraits<std::enable_if_t<Kokkos::is_space<Space>::value>, Space,
191 Prop...> {
192 // Specify Space, memory traits should be the only subsequent argument.
193
194 static_assert(
195 std::is_same<typename ViewTraits<void, Prop...>::execution_space,
196 void>::value &&
197 std::is_same<typename ViewTraits<void, Prop...>::memory_space,
198 void>::value &&
199 std::is_same<typename ViewTraits<void, Prop...>::HostMirrorSpace,
200 void>::value &&
201 std::is_same<typename ViewTraits<void, Prop...>::array_layout,
202 void>::value,
203 "Only one View Execution or Memory Space template argument");
204
205 using execution_space = typename Space::execution_space;
206 using memory_space = typename Space::memory_space;
207 using HostMirrorSpace =
208 typename Kokkos::Impl::HostMirror<Space>::Space::memory_space;
209 using array_layout = typename execution_space::array_layout;
210 using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
211 using specialize = typename ViewTraits<void, Prop...>::specialize;
212 using hooks_policy = typename ViewTraits<void, Prop...>::hooks_policy;
213};
214
215template <class MemoryTraits, class... Prop>
216struct ViewTraits<
217 std::enable_if_t<Kokkos::is_memory_traits<MemoryTraits>::value>,
218 MemoryTraits, Prop...> {
219 // Specify memory trait, should not be any subsequent arguments
220
221 static_assert(
222 std::is_same<typename ViewTraits<void, Prop...>::execution_space,
223 void>::value &&
224 std::is_same<typename ViewTraits<void, Prop...>::memory_space,
225 void>::value &&
226 std::is_same<typename ViewTraits<void, Prop...>::array_layout,
227 void>::value &&
228 std::is_same<typename ViewTraits<void, Prop...>::memory_traits,
229 void>::value &&
230 std::is_same<typename ViewTraits<void, Prop...>::hooks_policy,
231 void>::value,
232 "MemoryTrait is the final optional template argument for a View");
233
234 using execution_space = void;
235 using memory_space = void;
236 using HostMirrorSpace = void;
237 using array_layout = void;
238 using memory_traits = MemoryTraits;
239 using specialize = void;
240 using hooks_policy = void;
241};
242
243template <class DataType, class... Properties>
245 private:
246 // Unpack the properties arguments
247 using prop = ViewTraits<void, Properties...>;
248
249 using ExecutionSpace =
250 std::conditional_t<!std::is_void<typename prop::execution_space>::value,
251 typename prop::execution_space,
252 Kokkos::DefaultExecutionSpace>;
253
254 using MemorySpace =
255 std::conditional_t<!std::is_void<typename prop::memory_space>::value,
256 typename prop::memory_space,
257 typename ExecutionSpace::memory_space>;
258
259 using ArrayLayout =
260 std::conditional_t<!std::is_void<typename prop::array_layout>::value,
261 typename prop::array_layout,
262 typename ExecutionSpace::array_layout>;
263
264 using HostMirrorSpace = std::conditional_t<
265 !std::is_void<typename prop::HostMirrorSpace>::value,
266 typename prop::HostMirrorSpace,
267 typename Kokkos::Impl::HostMirror<ExecutionSpace>::Space>;
268
269 using MemoryTraits =
270 std::conditional_t<!std::is_void<typename prop::memory_traits>::value,
271 typename prop::memory_traits,
272 typename Kokkos::MemoryManaged>;
273
274 using HooksPolicy =
275 std::conditional_t<!std::is_void<typename prop::hooks_policy>::value,
276 typename prop::hooks_policy,
277 Kokkos::Experimental::DefaultViewHooks>;
278
279 // Analyze data type's properties,
280 // May be specialized based upon the layout and value type
281 using data_analysis = Kokkos::Impl::ViewDataAnalysis<DataType, ArrayLayout>;
282
283 public:
284 //------------------------------------
285 // Data type traits:
286
287 using data_type = typename data_analysis::type;
288 using const_data_type = typename data_analysis::const_type;
289 using non_const_data_type = typename data_analysis::non_const_type;
290
291 //------------------------------------
292 // Compatible array of trivial type traits:
293
294 using scalar_array_type = typename data_analysis::scalar_array_type;
295 using const_scalar_array_type =
296 typename data_analysis::const_scalar_array_type;
297 using non_const_scalar_array_type =
298 typename data_analysis::non_const_scalar_array_type;
299
300 //------------------------------------
301 // Value type traits:
302
303 using value_type = typename data_analysis::value_type;
304 using const_value_type = typename data_analysis::const_value_type;
305 using non_const_value_type = typename data_analysis::non_const_value_type;
306
307 //------------------------------------
308 // Mapping traits:
309
310 using array_layout = ArrayLayout;
311 using dimension = typename data_analysis::dimension;
312
313 using specialize = std::conditional_t<
314 std::is_void<typename data_analysis::specialize>::value,
315 typename prop::specialize,
316 typename data_analysis::specialize>; /* mapping specialization tag */
317
318 enum { rank = dimension::rank };
319 enum { rank_dynamic = dimension::rank_dynamic };
320
321 //------------------------------------
322 // Execution space, memory space, memory access traits, and host mirror space.
323
324 using execution_space = ExecutionSpace;
325 using memory_space = MemorySpace;
326 using device_type = Kokkos::Device<ExecutionSpace, MemorySpace>;
327 using memory_traits = MemoryTraits;
328 using host_mirror_space = HostMirrorSpace;
329 using hooks_policy = HooksPolicy;
330
331 using size_type = typename MemorySpace::size_type;
332
333 enum { is_hostspace = std::is_same<MemorySpace, HostSpace>::value };
334 enum { is_managed = MemoryTraits::is_unmanaged == 0 };
335 enum { is_random_access = MemoryTraits::is_random_access == 1 };
336
337 //------------------------------------
338};
339
424} // namespace Kokkos
425
426namespace Kokkos {
427
428template <class T1, class T2>
429struct is_always_assignable_impl;
430
431template <class... ViewTDst, class... ViewTSrc>
432struct is_always_assignable_impl<Kokkos::View<ViewTDst...>,
433 Kokkos::View<ViewTSrc...>> {
434 using mapping_type = Kokkos::Impl::ViewMapping<
435 typename Kokkos::View<ViewTDst...>::traits,
436 typename Kokkos::View<ViewTSrc...>::traits,
437 typename Kokkos::View<ViewTDst...>::traits::specialize>;
438
439 constexpr static bool value =
440 mapping_type::is_assignable &&
441 static_cast<int>(Kokkos::View<ViewTDst...>::rank_dynamic) >=
443};
444
445template <class View1, class View2>
446using is_always_assignable = is_always_assignable_impl<
447 std::remove_reference_t<View1>,
448 std::remove_const_t<std::remove_reference_t<View2>>>;
449
450template <class T1, class T2>
451inline constexpr bool is_always_assignable_v =
452 is_always_assignable<T1, T2>::value;
453
454template <class... ViewTDst, class... ViewTSrc>
455constexpr bool is_assignable(const Kokkos::View<ViewTDst...>& dst,
456 const Kokkos::View<ViewTSrc...>& src) {
457 using DstTraits = typename Kokkos::View<ViewTDst...>::traits;
458 using SrcTraits = typename Kokkos::View<ViewTSrc...>::traits;
459 using mapping_type =
460 Kokkos::Impl::ViewMapping<DstTraits, SrcTraits,
461 typename DstTraits::specialize>;
462
463 return is_always_assignable_v<Kokkos::View<ViewTDst...>,
464 Kokkos::View<ViewTSrc...>> ||
465 (mapping_type::is_assignable &&
466 ((DstTraits::dimension::rank_dynamic >= 1) ||
467 (dst.static_extent(0) == src.extent(0))) &&
468 ((DstTraits::dimension::rank_dynamic >= 2) ||
469 (dst.static_extent(1) == src.extent(1))) &&
470 ((DstTraits::dimension::rank_dynamic >= 3) ||
471 (dst.static_extent(2) == src.extent(2))) &&
472 ((DstTraits::dimension::rank_dynamic >= 4) ||
473 (dst.static_extent(3) == src.extent(3))) &&
474 ((DstTraits::dimension::rank_dynamic >= 5) ||
475 (dst.static_extent(4) == src.extent(4))) &&
476 ((DstTraits::dimension::rank_dynamic >= 6) ||
477 (dst.static_extent(5) == src.extent(5))) &&
478 ((DstTraits::dimension::rank_dynamic >= 7) ||
479 (dst.static_extent(6) == src.extent(6))) &&
480 ((DstTraits::dimension::rank_dynamic >= 8) ||
481 (dst.static_extent(7) == src.extent(7))));
482}
483
484} /* namespace Kokkos */
485
486//----------------------------------------------------------------------------
487//----------------------------------------------------------------------------
488
489#include <impl/Kokkos_ViewMapping.hpp>
490#include <impl/Kokkos_ViewArray.hpp>
491
492//----------------------------------------------------------------------------
493//----------------------------------------------------------------------------
494
495namespace Kokkos {
496
497namespace {
498
499constexpr Kokkos::Impl::ALL_t ALL = Kokkos::Impl::ALL_t();
500
501constexpr Kokkos::Impl::WithoutInitializing_t WithoutInitializing =
502 Kokkos::Impl::WithoutInitializing_t();
503
504constexpr Kokkos::Impl::AllowPadding_t AllowPadding =
505 Kokkos::Impl::AllowPadding_t();
506
507} // namespace
508
519template <class... Args>
520inline Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>
521view_alloc(Args const&... args) {
522 using return_type =
523 Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>;
524
525 static_assert(!return_type::has_pointer,
526 "Cannot give pointer-to-memory for view allocation");
527
528 return return_type(args...);
529}
530
531template <class... Args>
532KOKKOS_INLINE_FUNCTION
533 Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>
534 view_wrap(Args const&... args) {
535 using return_type =
536 Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>;
537
538 static_assert(!return_type::has_memory_space &&
539 !return_type::has_execution_space &&
540 !return_type::has_label && return_type::has_pointer,
541 "Must only give pointer-to-memory for view wrapping");
542
543 return return_type(args...);
544}
545
546} /* namespace Kokkos */
547
548//----------------------------------------------------------------------------
549//----------------------------------------------------------------------------
550
551namespace Kokkos {
552
553template <class DataType, class... Properties>
554class View;
555
556template <class>
557struct is_view : public std::false_type {};
558
559template <class D, class... P>
560struct is_view<View<D, P...>> : public std::true_type {};
561
562template <class D, class... P>
563struct is_view<const View<D, P...>> : public std::true_type {};
564
565template <class T>
566inline constexpr bool is_view_v = is_view<T>::value;
567
568template <class DataType, class... Properties>
569class View : public ViewTraits<DataType, Properties...> {
570 private:
571 template <class, class...>
572 friend class View;
573 template <class, class...>
574 friend class Kokkos::Impl::ViewMapping;
575
576 using view_tracker_type = Kokkos::Impl::ViewTracker<View>;
577
578 public:
579 using traits = ViewTraits<DataType, Properties...>;
580
581 private:
582 using map_type =
583 Kokkos::Impl::ViewMapping<traits, typename traits::specialize>;
584 template <typename V>
585 friend struct Kokkos::Impl::ViewTracker;
586 using hooks_policy = typename traits::hooks_policy;
587
588 view_tracker_type m_track;
589 map_type m_map;
590
591 public:
592 //----------------------------------------
595 View<typename traits::scalar_array_type, typename traits::array_layout,
596 typename traits::device_type, typename traits::hooks_policy,
597 typename traits::memory_traits>;
598
601 View<typename traits::const_data_type, typename traits::array_layout,
602 typename traits::device_type, typename traits::hooks_policy,
603 typename traits::memory_traits>;
604
607 View<typename traits::non_const_data_type, typename traits::array_layout,
608 typename traits::device_type, typename traits::hooks_policy,
609 typename traits::memory_traits>;
610
613 View<typename traits::non_const_data_type, typename traits::array_layout,
614 Device<DefaultHostExecutionSpace,
615 typename traits::host_mirror_space::memory_space>,
616 typename traits::hooks_policy>;
617
620 View<typename traits::non_const_data_type, typename traits::array_layout,
621 typename traits::host_mirror_space, typename traits::hooks_policy>;
622
624 using uniform_type = typename Impl::ViewUniformType<View, 0>::type;
625 using uniform_const_type =
626 typename Impl::ViewUniformType<View, 0>::const_type;
627 using uniform_runtime_type =
628 typename Impl::ViewUniformType<View, 0>::runtime_type;
629 using uniform_runtime_const_type =
630 typename Impl::ViewUniformType<View, 0>::runtime_const_type;
631 using uniform_nomemspace_type =
632 typename Impl::ViewUniformType<View, 0>::nomemspace_type;
633 using uniform_const_nomemspace_type =
634 typename Impl::ViewUniformType<View, 0>::const_nomemspace_type;
635 using uniform_runtime_nomemspace_type =
636 typename Impl::ViewUniformType<View, 0>::runtime_nomemspace_type;
637 using uniform_runtime_const_nomemspace_type =
638 typename Impl::ViewUniformType<View, 0>::runtime_const_nomemspace_type;
639
640 //----------------------------------------
641 // Domain rank and extents
642
643 enum { Rank = map_type::Rank };
644
647 // KOKKOS_INLINE_FUNCTION
648 // static
649 // constexpr unsigned rank() { return map_type::Rank; }
650
651 template <typename iType>
652 KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
653 std::is_integral<iType>::value, size_t>
654 extent(const iType& r) const noexcept {
655 return m_map.extent(r);
656 }
657
658 static KOKKOS_INLINE_FUNCTION constexpr size_t static_extent(
659 const unsigned r) noexcept {
660 return map_type::static_extent(r);
661 }
662
663 template <typename iType>
664 KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
665 std::is_integral<iType>::value, int>
666 extent_int(const iType& r) const noexcept {
667 return static_cast<int>(m_map.extent(r));
668 }
669
670 KOKKOS_INLINE_FUNCTION constexpr typename traits::array_layout layout()
671 const {
672 return m_map.layout();
673 }
674
675 //----------------------------------------
676 /* Deprecate all 'dimension' functions in favor of
677 * ISO/C++ vocabulary 'extent'.
678 */
679
680 KOKKOS_INLINE_FUNCTION constexpr size_t size() const {
681 return m_map.dimension_0() * m_map.dimension_1() * m_map.dimension_2() *
682 m_map.dimension_3() * m_map.dimension_4() * m_map.dimension_5() *
683 m_map.dimension_6() * m_map.dimension_7();
684 }
685
686 KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const {
687 return m_map.stride_0();
688 }
689 KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const {
690 return m_map.stride_1();
691 }
692 KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const {
693 return m_map.stride_2();
694 }
695 KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const {
696 return m_map.stride_3();
697 }
698 KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const {
699 return m_map.stride_4();
700 }
701 KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const {
702 return m_map.stride_5();
703 }
704 KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const {
705 return m_map.stride_6();
706 }
707 KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const {
708 return m_map.stride_7();
709 }
710
711 template <typename iType>
712 KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
713 std::is_integral<iType>::value, size_t>
714 stride(iType r) const {
715 return (
716 r == 0
717 ? m_map.stride_0()
718 : (r == 1
719 ? m_map.stride_1()
720 : (r == 2
721 ? m_map.stride_2()
722 : (r == 3
723 ? m_map.stride_3()
724 : (r == 4
725 ? m_map.stride_4()
726 : (r == 5
727 ? m_map.stride_5()
728 : (r == 6
729 ? m_map.stride_6()
730 : m_map.stride_7())))))));
731 }
732
733 template <typename iType>
734 KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
735 m_map.stride(s);
736 }
737
738 //----------------------------------------
739 // Range span is the span which contains all members.
740
741 using reference_type = typename map_type::reference_type;
742 using pointer_type = typename map_type::pointer_type;
743
744 enum {
745 reference_type_is_lvalue_reference =
746 std::is_lvalue_reference<reference_type>::value
747 };
748
749 KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return m_map.span(); }
750 KOKKOS_INLINE_FUNCTION bool span_is_contiguous() const {
751 return m_map.span_is_contiguous();
752 }
753 KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
754 return m_map.data() != nullptr;
755 }
756 KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
757 return m_map.data();
758 }
759
760 //----------------------------------------
761 // Allow specializations to query their specialized map
762
763 KOKKOS_INLINE_FUNCTION
764 const Kokkos::Impl::ViewMapping<traits, typename traits::specialize>&
765 impl_map() const {
766 return m_map;
767 }
768 KOKKOS_INLINE_FUNCTION
769 const Kokkos::Impl::SharedAllocationTracker& impl_track() const {
770 return m_track.m_tracker;
771 }
772 //----------------------------------------
773
774 private:
775 static constexpr bool is_layout_left =
776 std::is_same<typename traits::array_layout, Kokkos::LayoutLeft>::value;
777
778 static constexpr bool is_layout_right =
779 std::is_same<typename traits::array_layout, Kokkos::LayoutRight>::value;
780
781 static constexpr bool is_layout_stride =
782 std::is_same<typename traits::array_layout, Kokkos::LayoutStride>::value;
783
784 static constexpr bool is_default_map =
785 std::is_void<typename traits::specialize>::value &&
786 (is_layout_left || is_layout_right || is_layout_stride);
787
788#if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
789
790#define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(...) \
791 Kokkos::Impl::runtime_check_memory_access_violation< \
792 typename traits::memory_space>( \
793 "Kokkos::View ERROR: attempt to access inaccessible memory space", \
794 __VA_ARGS__); \
795 Kokkos::Impl::view_verify_operator_bounds<typename traits::memory_space>( \
796 __VA_ARGS__);
797
798#else
799
800#define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(...) \
801 Kokkos::Impl::runtime_check_memory_access_violation< \
802 typename traits::memory_space>( \
803 "Kokkos::View ERROR: attempt to access inaccessible memory space", \
804 __VA_ARGS__);
805
806#endif
807
808 template <typename... Is>
809 static KOKKOS_FUNCTION void check_access_member_function_valid_args(Is...) {
810 static_assert(Rank <= sizeof...(Is), "");
811 static_assert(sizeof...(Is) <= 8, "");
812 static_assert(Kokkos::Impl::are_integral<Is...>::value, "");
813 }
814
815 template <typename... Is>
816 static KOKKOS_FUNCTION void check_operator_parens_valid_args(Is...) {
817 static_assert(Rank == sizeof...(Is), "");
818 static_assert(Kokkos::Impl::are_integral<Is...>::value, "");
819 }
820
821 public:
822 //------------------------------
823 // Rank 1 default map operator()
824
825 template <typename I0>
826 KOKKOS_FORCEINLINE_FUNCTION
827 std::enable_if_t<(Kokkos::Impl::always_true<I0>::value && //
828 (1 == Rank) && is_default_map && !is_layout_stride),
829 reference_type>
830 operator()(I0 i0) const {
831 check_operator_parens_valid_args(i0);
832 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
833 return m_map.m_impl_handle[i0];
834 }
835
836 template <typename I0>
837 KOKKOS_FORCEINLINE_FUNCTION
838 std::enable_if_t<(Kokkos::Impl::always_true<I0>::value && //
839 (1 == Rank) && is_default_map && is_layout_stride),
840 reference_type>
841 operator()(I0 i0) const {
842 check_operator_parens_valid_args(i0);
843 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
844 return m_map.m_impl_handle[m_map.m_impl_offset.m_stride.S0 * i0];
845 }
846
847 //------------------------------
848 // Rank 1 operator[]
849
850 template <typename I0>
851 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
852 ((1 == Rank) && Kokkos::Impl::are_integral<I0>::value && !is_default_map),
853 reference_type>
854 operator[](I0 i0) const {
855 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
856 return m_map.reference(i0);
857 }
858
859 template <typename I0>
860 KOKKOS_FORCEINLINE_FUNCTION
861 std::enable_if_t<((1 == Rank) && Kokkos::Impl::are_integral<I0>::value &&
862 is_default_map && !is_layout_stride),
863 reference_type>
864 operator[](I0 i0) const {
865 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
866 return m_map.m_impl_handle[i0];
867 }
868
869 template <typename I0>
870 KOKKOS_FORCEINLINE_FUNCTION
871 std::enable_if_t<((1 == Rank) && Kokkos::Impl::are_integral<I0>::value &&
872 is_default_map && is_layout_stride),
873 reference_type>
874 operator[](I0 i0) const {
875 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
876 return m_map.m_impl_handle[m_map.m_impl_offset.m_stride.S0 * i0];
877 }
878
879 //------------------------------
880 // Rank 2 default map operator()
881
882 template <typename I0, typename I1>
883 KOKKOS_FORCEINLINE_FUNCTION
884 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1>::value && //
885 (2 == Rank) && is_default_map && is_layout_left &&
886 (traits::rank_dynamic == 0)),
887 reference_type>
888 operator()(I0 i0, I1 i1) const {
889 check_operator_parens_valid_args(i0, i1);
890 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
891 return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_dim.N0 * i1];
892 }
893
894 template <typename I0, typename I1>
895 KOKKOS_FORCEINLINE_FUNCTION
896 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1>::value && //
897 (2 == Rank) && is_default_map && is_layout_left &&
898 (traits::rank_dynamic != 0)),
899 reference_type>
900 operator()(I0 i0, I1 i1) const {
901 check_operator_parens_valid_args(i0, i1);
902 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
903 return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_stride * i1];
904 }
905
906 template <typename I0, typename I1>
907 KOKKOS_FORCEINLINE_FUNCTION
908 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1>::value && //
909 (2 == Rank) && is_default_map && is_layout_right &&
910 (traits::rank_dynamic == 0)),
911 reference_type>
912 operator()(I0 i0, I1 i1) const {
913 check_operator_parens_valid_args(i0, i1);
914 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
915 return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_dim.N1 * i0];
916 }
917
918 template <typename I0, typename I1>
919 KOKKOS_FORCEINLINE_FUNCTION
920 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1>::value && //
921 (2 == Rank) && is_default_map && is_layout_right &&
922 (traits::rank_dynamic != 0)),
923 reference_type>
924 operator()(I0 i0, I1 i1) const {
925 check_operator_parens_valid_args(i0, i1);
926 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
927 return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_stride * i0];
928 }
929
930 template <typename I0, typename I1>
931 KOKKOS_FORCEINLINE_FUNCTION
932 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1>::value && //
933 (2 == Rank) && is_default_map && is_layout_stride),
934 reference_type>
935 operator()(I0 i0, I1 i1) const {
936 check_operator_parens_valid_args(i0, i1);
937 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
938 return m_map.m_impl_handle[i0 * m_map.m_impl_offset.m_stride.S0 +
939 i1 * m_map.m_impl_offset.m_stride.S1];
940 }
941
942 // Rank 0 -> 8 operator() except for rank-1 and rank-2 with default map which
943 // have "inlined" versions above
944
945 template <typename... Is>
946 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
947 (Kokkos::Impl::always_true<Is...>::value && //
948 (2 != Rank) && (1 != Rank) && (0 != Rank) && is_default_map),
949 reference_type>
950 operator()(Is... indices) const {
951 check_operator_parens_valid_args(indices...);
952 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, indices...)
953 return m_map.m_impl_handle[m_map.m_impl_offset(indices...)];
954 }
955
956 template <typename... Is>
957 KOKKOS_FORCEINLINE_FUNCTION
958 std::enable_if_t<(Kokkos::Impl::always_true<Is...>::value && //
959 ((0 == Rank) || !is_default_map)),
960 reference_type>
961 operator()(Is... indices) const {
962 check_operator_parens_valid_args(indices...);
963 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, indices...)
964 return m_map.reference(indices...);
965 }
966
967 //------------------------------
968 // Rank 0
969
970 template <typename... Is>
971 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
972 (Kokkos::Impl::always_true<Is...>::value && (0 == Rank)), reference_type>
973 access(Is... extra) const {
974 check_access_member_function_valid_args(extra...);
975 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, extra...)
976 return m_map.reference();
977 }
978
979 //------------------------------
980 // Rank 1
981
982 template <typename I0, typename... Is>
983 KOKKOS_FORCEINLINE_FUNCTION
984 std::enable_if_t<(Kokkos::Impl::always_true<I0, Is...>::value &&
985 (1 == Rank) && !is_default_map),
986 reference_type>
987 access(I0 i0, Is... extra) const {
988 check_access_member_function_valid_args(i0, extra...);
989 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, extra...)
990 return m_map.reference(i0);
991 }
992
993 template <typename I0, typename... Is>
994 KOKKOS_FORCEINLINE_FUNCTION
995 std::enable_if_t<(Kokkos::Impl::always_true<I0, Is...>::value &&
996 (1 == Rank) && is_default_map && !is_layout_stride),
997 reference_type>
998 access(I0 i0, Is... extra) const {
999 check_access_member_function_valid_args(i0, extra...);
1000 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, extra...)
1001 return m_map.m_impl_handle[i0];
1002 }
1003
1004 template <typename I0, typename... Is>
1005 KOKKOS_FORCEINLINE_FUNCTION
1006 std::enable_if_t<(Kokkos::Impl::always_true<I0, Is...>::value &&
1007 (1 == Rank) && is_default_map && is_layout_stride),
1008 reference_type>
1009 access(I0 i0, Is... extra) const {
1010 check_access_member_function_valid_args(i0, extra...);
1011 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, extra...)
1012 return m_map.m_impl_handle[m_map.m_impl_offset.m_stride.S0 * i0];
1013 }
1014
1015 //------------------------------
1016 // Rank 2
1017
1018 template <typename I0, typename I1, typename... Is>
1019 KOKKOS_FORCEINLINE_FUNCTION
1020 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, Is...>::value &&
1021 (2 == Rank) && !is_default_map),
1022 reference_type>
1023 access(I0 i0, I1 i1, Is... extra) const {
1024 check_access_member_function_valid_args(i0, i1, extra...);
1025 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1026 return m_map.reference(i0, i1);
1027 }
1028
1029 template <typename I0, typename I1, typename... Is>
1030 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1031 (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == Rank) &&
1032 is_default_map && is_layout_left && (traits::rank_dynamic == 0)),
1033 reference_type>
1034 access(I0 i0, I1 i1, Is... extra) const {
1035 check_access_member_function_valid_args(i0, i1, extra...);
1036 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1037 return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_dim.N0 * i1];
1038 }
1039
1040 template <typename I0, typename I1, typename... Is>
1041 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1042 (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == Rank) &&
1043 is_default_map && is_layout_left && (traits::rank_dynamic != 0)),
1044 reference_type>
1045 access(I0 i0, I1 i1, Is... extra) const {
1046 check_access_member_function_valid_args(i0, i1, extra...);
1047 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1048 return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_stride * i1];
1049 }
1050
1051 template <typename I0, typename I1, typename... Is>
1052 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1053 (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == Rank) &&
1054 is_default_map && is_layout_right && (traits::rank_dynamic == 0)),
1055 reference_type>
1056 access(I0 i0, I1 i1, Is... extra) const {
1057 check_access_member_function_valid_args(i0, i1, extra...);
1058 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1059 return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_dim.N1 * i0];
1060 }
1061
1062 template <typename I0, typename I1, typename... Is>
1063 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1064 (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == Rank) &&
1065 is_default_map && is_layout_right && (traits::rank_dynamic != 0)),
1066 reference_type>
1067 access(I0 i0, I1 i1, Is... extra) const {
1068 check_access_member_function_valid_args(i0, i1, extra...);
1069 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1070 return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_stride * i0];
1071 }
1072
1073 template <typename I0, typename I1, typename... Is>
1074 KOKKOS_FORCEINLINE_FUNCTION
1075 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, Is...>::value &&
1076 (2 == Rank) && is_default_map && is_layout_stride),
1077 reference_type>
1078 access(I0 i0, I1 i1, Is... extra) const {
1079 check_access_member_function_valid_args(i0, i1, extra...);
1080 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1081 return m_map.m_impl_handle[i0 * m_map.m_impl_offset.m_stride.S0 +
1082 i1 * m_map.m_impl_offset.m_stride.S1];
1083 }
1084
1085 //------------------------------
1086 // Rank 3
1087
1088 template <typename I0, typename I1, typename I2, typename... Is>
1089 KOKKOS_FORCEINLINE_FUNCTION
1090 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, Is...>::value &&
1091 (3 == Rank) && is_default_map),
1092 reference_type>
1093 access(I0 i0, I1 i1, I2 i2, Is... extra) const {
1094 check_access_member_function_valid_args(i0, i1, i2, extra...);
1095 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, extra...)
1096 return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2)];
1097 }
1098
1099 template <typename I0, typename I1, typename I2, typename... Is>
1100 KOKKOS_FORCEINLINE_FUNCTION
1101 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, Is...>::value &&
1102 (3 == Rank) && !is_default_map),
1103 reference_type>
1104 access(I0 i0, I1 i1, I2 i2, Is... extra) const {
1105 check_access_member_function_valid_args(i0, i1, i2, extra...);
1106 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, extra...)
1107 return m_map.reference(i0, i1, i2);
1108 }
1109
1110 //------------------------------
1111 // Rank 4
1112
1113 template <typename I0, typename I1, typename I2, typename I3, typename... Is>
1114 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1115 (Kokkos::Impl::always_true<I0, I1, I2, I3, Is...>::value && (4 == Rank) &&
1116 is_default_map),
1117 reference_type>
1118 access(I0 i0, I1 i1, I2 i2, I3 i3, Is... extra) const {
1119 check_access_member_function_valid_args(i0, i1, i2, i3, extra...);
1120 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, extra...)
1121 return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3)];
1122 }
1123
1124 template <typename I0, typename I1, typename I2, typename I3, typename... Is>
1125 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1126 (Kokkos::Impl::always_true<I0, I1, I2, I3, Is...>::value && (4 == Rank) &&
1127 !is_default_map),
1128 reference_type>
1129 access(I0 i0, I1 i1, I2 i2, I3 i3, Is... extra) const {
1130 check_access_member_function_valid_args(i0, i1, i2, i3, extra...);
1131 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, extra...)
1132 return m_map.reference(i0, i1, i2, i3);
1133 }
1134
1135 //------------------------------
1136 // Rank 5
1137
1138 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1139 typename... Is>
1140 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1141 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, Is...>::value &&
1142 (5 == Rank) && is_default_map),
1143 reference_type>
1144 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, Is... extra) const {
1145 check_access_member_function_valid_args(i0, i1, i2, i3, i4, extra...);
1146 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4,
1147 extra...)
1148 return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4)];
1149 }
1150
1151 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1152 typename... Is>
1153 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1154 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, Is...>::value &&
1155 (5 == Rank) && !is_default_map),
1156 reference_type>
1157 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, Is... extra) const {
1158 check_access_member_function_valid_args(i0, i1, i2, i3, i4, extra...);
1159 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4,
1160 extra...)
1161 return m_map.reference(i0, i1, i2, i3, i4);
1162 }
1163
1164 //------------------------------
1165 // Rank 6
1166
1167 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1168 typename I5, typename... Is>
1169 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1170 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, Is...>::value &&
1171 (6 == Rank) && is_default_map),
1172 reference_type>
1173 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, Is... extra) const {
1174 check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, extra...);
1175 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5,
1176 extra...)
1177 return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4, i5)];
1178 }
1179
1180 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1181 typename I5, typename... Is>
1182 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1183 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, Is...>::value &&
1184 (6 == Rank) && !is_default_map),
1185 reference_type>
1186 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, Is... extra) const {
1187 check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, extra...);
1188 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5,
1189 extra...)
1190 return m_map.reference(i0, i1, i2, i3, i4, i5);
1191 }
1192
1193 //------------------------------
1194 // Rank 7
1195
1196 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1197 typename I5, typename I6, typename... Is>
1198 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1199 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6, Is...>::value &&
1200 (7 == Rank) && is_default_map),
1201 reference_type>
1202 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, Is... extra) const {
1203 check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6,
1204 extra...);
1205 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1206 extra...)
1207 return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4, i5, i6)];
1208 }
1209
1210 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1211 typename I5, typename I6, typename... Is>
1212 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1213 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6, Is...>::value &&
1214 (7 == Rank) && !is_default_map),
1215 reference_type>
1216 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, Is... extra) const {
1217 check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6,
1218 extra...);
1219 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1220 extra...)
1221 return m_map.reference(i0, i1, i2, i3, i4, i5, i6);
1222 }
1223
1224 //------------------------------
1225 // Rank 8
1226
1227 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1228 typename I5, typename I6, typename I7, typename... Is>
1229 KOKKOS_FORCEINLINE_FUNCTION
1230 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6,
1231 I7, Is...>::value &&
1232 (8 == Rank) && is_default_map),
1233 reference_type>
1234 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, I7 i7,
1235 Is... extra) const {
1236 check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6, i7,
1237 extra...);
1238 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1239 i7, extra...)
1240 return m_map
1241 .m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4, i5, i6, i7)];
1242 }
1243
1244 template <typename I0, typename I1, typename I2, typename I3, typename I4,
1245 typename I5, typename I6, typename I7, typename... Is>
1246 KOKKOS_FORCEINLINE_FUNCTION
1247 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6,
1248 I7, Is...>::value &&
1249 (8 == Rank) && !is_default_map),
1250 reference_type>
1251 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, I7 i7,
1252 Is... extra) const {
1253 check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6, i7,
1254 extra...);
1255 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1256 i7, extra...)
1257 return m_map.reference(i0, i1, i2, i3, i4, i5, i6, i7);
1258 }
1259
1260#undef KOKKOS_IMPL_VIEW_OPERATOR_VERIFY
1261
1262 //----------------------------------------
1263 // Standard destructor, constructors, and assignment operators
1264
1265 KOKKOS_DEFAULTED_FUNCTION
1266 ~View() = default;
1267
1268 KOKKOS_DEFAULTED_FUNCTION
1269 View() = default;
1270
1271 KOKKOS_FUNCTION
1272 View(const View& other) : m_track(other.m_track), m_map(other.m_map) {
1273 KOKKOS_IF_ON_HOST((hooks_policy::copy_construct(*this, other);))
1274 }
1275
1276 KOKKOS_FUNCTION
1277 View(View&& other)
1278 : m_track{std::move(other.m_track)}, m_map{std::move(other.m_map)} {
1279 KOKKOS_IF_ON_HOST((hooks_policy::move_construct(*this, other);))
1280 }
1281
1282 KOKKOS_FUNCTION
1283 View& operator=(const View& other) {
1284 m_map = other.m_map;
1285 m_track = other.m_track;
1286
1287 KOKKOS_IF_ON_HOST((hooks_policy::copy_assign(*this, other);))
1288
1289 return *this;
1290 }
1291
1292 KOKKOS_FUNCTION
1293 View& operator=(View&& other) {
1294 m_map = std::move(other.m_map);
1295 m_track = std::move(other.m_track);
1296
1297 KOKKOS_IF_ON_HOST((hooks_policy::move_assign(*this, other);))
1298
1299 return *this;
1300 }
1301
1302 //----------------------------------------
1303 // Compatible view copy constructor and assignment
1304 // may assign unmanaged from managed.
1305
1306 template <class RT, class... RP>
1307 KOKKOS_INLINE_FUNCTION View(
1308 const View<RT, RP...>& rhs,
1309 std::enable_if_t<Kokkos::Impl::ViewMapping<
1310 traits, typename View<RT, RP...>::traits,
1311 typename traits::specialize>::is_assignable_data_type>* = nullptr)
1312 : m_track(rhs), m_map() {
1313 using SrcTraits = typename View<RT, RP...>::traits;
1314 using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1315 typename traits::specialize>;
1316 static_assert(Mapping::is_assignable,
1317 "Incompatible View copy construction");
1318 Mapping::assign(m_map, rhs.m_map, rhs.m_track.m_tracker);
1319 }
1320
1321 template <class RT, class... RP>
1322 KOKKOS_INLINE_FUNCTION std::enable_if_t<
1323 Kokkos::Impl::ViewMapping<
1324 traits, typename View<RT, RP...>::traits,
1325 typename traits::specialize>::is_assignable_data_type,
1326 View>&
1327 operator=(const View<RT, RP...>& rhs) {
1328 using SrcTraits = typename View<RT, RP...>::traits;
1329 using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1330 typename traits::specialize>;
1331 static_assert(Mapping::is_assignable, "Incompatible View copy assignment");
1332 Mapping::assign(m_map, rhs.m_map, rhs.m_track.m_tracker);
1333 m_track.assign(rhs);
1334 return *this;
1335 }
1336
1337 //----------------------------------------
1338 // Compatible subview constructor
1339 // may assign unmanaged from managed.
1340
1341 template <class RT, class... RP, class Arg0, class... Args>
1342 KOKKOS_INLINE_FUNCTION View(const View<RT, RP...>& src_view, const Arg0 arg0,
1343 Args... args)
1344 : m_track(src_view), m_map() {
1345 using SrcType = View<RT, RP...>;
1346
1347 using Mapping = Kokkos::Impl::ViewMapping<void, typename SrcType::traits,
1348 Arg0, Args...>;
1349
1350 using DstType = typename Mapping::type;
1351
1352 static_assert(
1353 Kokkos::Impl::ViewMapping<traits, typename DstType::traits,
1354 typename traits::specialize>::is_assignable,
1355 "Subview construction requires compatible view and subview arguments");
1356
1357 Mapping::assign(m_map, src_view.m_map, arg0, args...);
1358 }
1359
1360 //----------------------------------------
1361 // Allocation tracking properties
1362
1363 KOKKOS_INLINE_FUNCTION
1364 int use_count() const { return m_track.m_tracker.use_count(); }
1365
1366 inline const std::string label() const {
1367 return m_track.m_tracker
1368 .template get_label<typename traits::memory_space>();
1369 }
1370
1371 public:
1372 //----------------------------------------
1373 // Allocation according to allocation properties and array layout
1374
1375 template <class... P>
1376 explicit inline View(
1377 const Impl::ViewCtorProp<P...>& arg_prop,
1378 std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer,
1379 typename traits::array_layout> const& arg_layout)
1380 : m_track(), m_map() {
1381 // Copy the input allocation properties with possibly defaulted properties
1382 // We need to split it in two to avoid MSVC compiler errors
1383 auto prop_copy_tmp =
1384 Impl::with_properties_if_unset(arg_prop, std::string{});
1385 auto prop_copy = Impl::with_properties_if_unset(
1386 prop_copy_tmp, typename traits::device_type::memory_space{},
1387 typename traits::device_type::execution_space{});
1388 using alloc_prop = decltype(prop_copy);
1389
1390 static_assert(traits::is_managed,
1391 "View allocation constructor requires managed memory");
1392
1393 if (alloc_prop::initialize &&
1394 !alloc_prop::execution_space::impl_is_initialized()) {
1395 // If initializing view data then
1396 // the execution space must be initialized.
1397 Kokkos::Impl::throw_runtime_exception(
1398 "Constructing View and initializing data with uninitialized "
1399 "execution space");
1400 }
1401
1402 size_t i0 = arg_layout.dimension[0];
1403 size_t i1 = arg_layout.dimension[1];
1404 size_t i2 = arg_layout.dimension[2];
1405 size_t i3 = arg_layout.dimension[3];
1406 size_t i4 = arg_layout.dimension[4];
1407 size_t i5 = arg_layout.dimension[5];
1408 size_t i6 = arg_layout.dimension[6];
1409 size_t i7 = arg_layout.dimension[7];
1410
1411 const std::string& alloc_name =
1412 Impl::get_property<Impl::LabelTag>(prop_copy);
1413 Impl::runtime_check_rank(
1414 traits::rank, traits::rank_dynamic,
1415 std::is_same<typename traits::specialize, void>::value, i0, i1, i2, i3,
1416 i4, i5, i6, i7, alloc_name);
1417
1418//------------------------------------------------------------
1419#if defined(KOKKOS_ENABLE_CUDA)
1420 // If allocating in CudaUVMSpace must fence before and after
1421 // the allocation to protect against possible concurrent access
1422 // on the CPU and the GPU.
1423 // Fence using the trait's execution space (which will be Kokkos::Cuda)
1424 // to avoid incomplete type errors from using Kokkos::Cuda directly.
1425 if (std::is_same<Kokkos::CudaUVMSpace,
1426 typename traits::device_type::memory_space>::value) {
1427 typename traits::device_type::memory_space::execution_space().fence(
1428 "Kokkos::View<...>::View: fence before allocating UVM");
1429 }
1430#endif
1431 //------------------------------------------------------------
1432
1433 Kokkos::Impl::SharedAllocationRecord<>* record = m_map.allocate_shared(
1434 prop_copy, arg_layout, Impl::ViewCtorProp<P...>::has_execution_space);
1435
1436//------------------------------------------------------------
1437#if defined(KOKKOS_ENABLE_CUDA)
1438 if (std::is_same<Kokkos::CudaUVMSpace,
1439 typename traits::device_type::memory_space>::value) {
1440 typename traits::device_type::memory_space::execution_space().fence(
1441 "Kokkos::View<...>::View: fence after allocating UVM");
1442 }
1443#endif
1444 //------------------------------------------------------------
1445
1446 // Setup and initialization complete, start tracking
1447 m_track.m_tracker.assign_allocated_record_to_uninitialized(record);
1448 }
1449
1450 KOKKOS_INLINE_FUNCTION
1451 void assign_data(pointer_type arg_data) {
1452 m_track.m_tracker.clear();
1453 m_map.assign_data(arg_data);
1454 }
1455
1456 // Wrap memory according to properties and array layout
1457 template <class... P>
1458 explicit KOKKOS_INLINE_FUNCTION View(
1459 const Impl::ViewCtorProp<P...>& arg_prop,
1460 std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer,
1461 typename traits::array_layout> const& arg_layout)
1462 : m_track() // No memory tracking
1463 ,
1464 m_map(arg_prop, arg_layout) {
1465 static_assert(
1466 std::is_same<pointer_type,
1467 typename Impl::ViewCtorProp<P...>::pointer_type>::value,
1468 "Constructing View to wrap user memory must supply matching pointer "
1469 "type");
1470 }
1471
1472 // Simple dimension-only layout
1473 template <class... P>
1474 explicit inline View(
1475 const Impl::ViewCtorProp<P...>& arg_prop,
1476 std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer, size_t> const
1477 arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1478 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1479 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1480 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1481 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1482 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1483 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1484 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1485 : View(arg_prop,
1486 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1487 arg_N4, arg_N5, arg_N6, arg_N7)) {
1488 static_assert(traits::array_layout::is_extent_constructible,
1489 "Layout is not constructible from extent arguments. Use "
1490 "overload taking a layout object instead.");
1491 }
1492
1493 template <class... P>
1494 explicit KOKKOS_INLINE_FUNCTION View(
1495 const Impl::ViewCtorProp<P...>& arg_prop,
1496 std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer, size_t> const
1497 arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1498 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1499 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1500 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1501 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1502 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1503 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1504 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1505 : View(arg_prop,
1506 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1507 arg_N4, arg_N5, arg_N6, arg_N7)) {
1508 static_assert(traits::array_layout::is_extent_constructible,
1509 "Layout is not constructible from extent arguments. Use "
1510 "overload taking a layout object instead.");
1511 }
1512
1513 // Allocate with label and layout
1514 template <typename Label>
1515 explicit inline View(
1516 const Label& arg_label,
1517 std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value,
1518 typename traits::array_layout> const& arg_layout)
1519 : View(Impl::ViewCtorProp<std::string>(arg_label), arg_layout) {}
1520
1521 // Allocate label and layout, must disambiguate from subview constructor.
1522 template <typename Label>
1523 explicit inline View(
1524 const Label& arg_label,
1525 std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value, const size_t>
1526 arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1527 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1528 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1529 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1530 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1531 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1532 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1533 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1534 : View(Impl::ViewCtorProp<std::string>(arg_label),
1535 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1536 arg_N4, arg_N5, arg_N6, arg_N7)) {
1537 static_assert(traits::array_layout::is_extent_constructible,
1538 "Layout is not constructible from extent arguments. Use "
1539 "overload taking a layout object instead.");
1540 }
1541
1542 // Construct view from ViewTracker and map
1543 // This should be the preferred method because future extensions may need to
1544 // use the ViewTracker class.
1545 template <class Traits>
1546 KOKKOS_INLINE_FUNCTION View(
1547 const view_tracker_type& track,
1548 const Kokkos::Impl::ViewMapping<Traits, typename Traits::specialize>& map)
1549 : m_track(track), m_map() {
1550 using Mapping =
1551 Kokkos::Impl::ViewMapping<traits, Traits, typename traits::specialize>;
1552 static_assert(Mapping::is_assignable,
1553 "Incompatible View copy construction");
1554 Mapping::assign(m_map, map, track.m_tracker);
1555 }
1556
1557 // Construct View from internal shared allocation tracker object and map
1558 // This is here for backwards compatibility for classes that derive from
1559 // Kokkos::View
1560 template <class Traits>
1561 KOKKOS_INLINE_FUNCTION View(
1562 const typename view_tracker_type::track_type& track,
1563 const Kokkos::Impl::ViewMapping<Traits, typename Traits::specialize>& map)
1564 : m_track(track), m_map() {
1565 using Mapping =
1566 Kokkos::Impl::ViewMapping<traits, Traits, typename traits::specialize>;
1567 static_assert(Mapping::is_assignable,
1568 "Incompatible View copy construction");
1569 Mapping::assign(m_map, map, track);
1570 }
1571
1572 //----------------------------------------
1573 // Memory span required to wrap these dimensions.
1574 static constexpr size_t required_allocation_size(
1575 typename traits::array_layout const& layout) {
1576 return map_type::memory_span(layout);
1577 }
1578
1579 static constexpr size_t required_allocation_size(
1580 const size_t arg_N0 = 0, const size_t arg_N1 = 0, const size_t arg_N2 = 0,
1581 const size_t arg_N3 = 0, const size_t arg_N4 = 0, const size_t arg_N5 = 0,
1582 const size_t arg_N6 = 0, const size_t arg_N7 = 0) {
1583 static_assert(traits::array_layout::is_extent_constructible,
1584 "Layout is not constructible from extent arguments. Use "
1585 "overload taking a layout object instead.");
1586 return map_type::memory_span(typename traits::array_layout(
1587 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1588 }
1589
1590 explicit KOKKOS_INLINE_FUNCTION View(
1591 pointer_type arg_ptr, const size_t arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1592 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1593 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1594 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1595 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1596 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1597 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1598 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1599 : View(Impl::ViewCtorProp<pointer_type>(arg_ptr),
1600 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1601 arg_N4, arg_N5, arg_N6, arg_N7)) {
1602 static_assert(traits::array_layout::is_extent_constructible,
1603 "Layout is not constructible from extent arguments. Use "
1604 "overload taking a layout object instead.");
1605 }
1606
1607 explicit KOKKOS_INLINE_FUNCTION View(
1608 pointer_type arg_ptr, const typename traits::array_layout& arg_layout)
1609 : View(Impl::ViewCtorProp<pointer_type>(arg_ptr), arg_layout) {}
1610
1611 //----------------------------------------
1612 // Shared scratch memory constructor
1613
1614 static KOKKOS_INLINE_FUNCTION size_t
1615 shmem_size(const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1616 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1617 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1618 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1619 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1620 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1621 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1622 const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
1623 static_assert(traits::array_layout::is_extent_constructible,
1624 "Layout is not constructible from extent arguments. Use "
1625 "overload taking a layout object instead.");
1626 const size_t num_passed_args = Impl::count_valid_integers(
1627 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7);
1628
1629 if (std::is_void<typename traits::specialize>::value &&
1630 num_passed_args != traits::rank_dynamic) {
1631 Kokkos::abort(
1632 "Kokkos::View::shmem_size() rank_dynamic != number of arguments.\n");
1633 }
1634
1635 return View::shmem_size(typename traits::array_layout(
1636 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1637 }
1638
1639 private:
1640 // Want to be able to align to minimum scratch alignment or sizeof or alignof
1641 // elements
1642 static constexpr size_t scratch_value_alignment =
1643 max({sizeof(typename traits::value_type),
1644 alignof(typename traits::value_type),
1645 static_cast<size_t>(
1646 traits::execution_space::scratch_memory_space::ALIGN)});
1647
1648 public:
1649 static KOKKOS_INLINE_FUNCTION size_t
1650 shmem_size(typename traits::array_layout const& arg_layout) {
1651 return map_type::memory_span(arg_layout) + scratch_value_alignment;
1652 }
1653
1654 explicit KOKKOS_INLINE_FUNCTION View(
1655 const typename traits::execution_space::scratch_memory_space& arg_space,
1656 const typename traits::array_layout& arg_layout)
1657 : View(Impl::ViewCtorProp<pointer_type>(reinterpret_cast<pointer_type>(
1658 arg_space.get_shmem_aligned(map_type::memory_span(arg_layout),
1659 scratch_value_alignment))),
1660 arg_layout) {}
1661
1662 explicit KOKKOS_INLINE_FUNCTION View(
1663 const typename traits::execution_space::scratch_memory_space& arg_space,
1664 const size_t arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1665 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1666 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1667 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1668 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1669 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1670 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1671 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1672 : View(Impl::ViewCtorProp<pointer_type>(
1673 reinterpret_cast<pointer_type>(arg_space.get_shmem_aligned(
1674 map_type::memory_span(typename traits::array_layout(
1675 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
1676 arg_N7)),
1677 scratch_value_alignment))),
1678 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1679 arg_N4, arg_N5, arg_N6, arg_N7)) {
1680 static_assert(traits::array_layout::is_extent_constructible,
1681 "Layout is not constructible from extent arguments. Use "
1682 "overload taking a layout object instead.");
1683 }
1684};
1685
1690template <typename D, class... P>
1691KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const View<D, P...>& V) {
1692 return V.Rank;
1693} // Temporary until added to view
1694
1695namespace Impl {
1696
1697template <typename ValueType, unsigned int Rank>
1698struct RankDataType {
1699 using type = typename RankDataType<ValueType, Rank - 1>::type*;
1700};
1701
1702template <typename ValueType>
1703struct RankDataType<ValueType, 0> {
1704 using type = ValueType;
1705};
1706
1707template <unsigned N, typename... Args>
1708KOKKOS_FUNCTION std::enable_if_t<
1709 N == View<Args...>::Rank &&
1710 std::is_same<typename ViewTraits<Args...>::specialize, void>::value,
1711 View<Args...>>
1712as_view_of_rank_n(View<Args...> v) {
1713 return v;
1714}
1715
1716// Placeholder implementation to compile generic code for DynRankView; should
1717// never be called
1718template <unsigned N, typename T, typename... Args>
1719KOKKOS_FUNCTION std::enable_if_t<
1720 N != View<T, Args...>::Rank &&
1721 std::is_same<typename ViewTraits<T, Args...>::specialize, void>::value,
1722 View<typename RankDataType<typename View<T, Args...>::value_type, N>::type,
1723 Args...>>
1724as_view_of_rank_n(View<T, Args...>) {
1725 Kokkos::abort("Trying to get at a View of the wrong rank");
1726 return {};
1727}
1728
1729template <typename Function, typename... Args>
1730void apply_to_view_of_static_rank(Function&& f, View<Args...> a) {
1731 f(a);
1732}
1733
1734} // namespace Impl
1735//----------------------------------------------------------------------------
1736//----------------------------------------------------------------------------
1737
1738template <class V, class... Args>
1739using Subview =
1740 typename Kokkos::Impl::ViewMapping<void /* deduce subview type from source
1741 view traits */
1742 ,
1743 typename V::traits, Args...>::type;
1744
1745template <class D, class... P, class... Args>
1746KOKKOS_INLINE_FUNCTION
1747 typename Kokkos::Impl::ViewMapping<void /* deduce subview type from source
1748 view traits */
1749 ,
1750 ViewTraits<D, P...>, Args...>::type
1751 subview(const View<D, P...>& src, Args... args) {
1752 static_assert(View<D, P...>::Rank == sizeof...(Args),
1753 "subview requires one argument for each source View rank");
1754
1755 return typename Kokkos::Impl::ViewMapping<
1756 void /* deduce subview type from source view traits */
1757 ,
1758 ViewTraits<D, P...>, Args...>::type(src, args...);
1759}
1760
1761template <class MemoryTraits, class D, class... P, class... Args>
1762KOKKOS_INLINE_FUNCTION typename Kokkos::Impl::ViewMapping<
1763 void /* deduce subview type from source view traits */
1764 ,
1765 ViewTraits<D, P...>, Args...>::template apply<MemoryTraits>::type
1766subview(const View<D, P...>& src, Args... args) {
1767 static_assert(View<D, P...>::Rank == sizeof...(Args),
1768 "subview requires one argument for each source View rank");
1769
1770 return typename Kokkos::Impl::ViewMapping<
1771 void /* deduce subview type from source view traits */
1772 ,
1773 ViewTraits<D, P...>,
1774 Args...>::template apply<MemoryTraits>::type(src, args...);
1775}
1776
1777} /* namespace Kokkos */
1778
1779//----------------------------------------------------------------------------
1780//----------------------------------------------------------------------------
1781
1782namespace Kokkos {
1783
1784template <class LT, class... LP, class RT, class... RP>
1785KOKKOS_INLINE_FUNCTION bool operator==(const View<LT, LP...>& lhs,
1786 const View<RT, RP...>& rhs) {
1787 // Same data, layout, dimensions
1788 using lhs_traits = ViewTraits<LT, LP...>;
1789 using rhs_traits = ViewTraits<RT, RP...>;
1790
1791 return std::is_same<typename lhs_traits::const_value_type,
1792 typename rhs_traits::const_value_type>::value &&
1793 std::is_same<typename lhs_traits::array_layout,
1794 typename rhs_traits::array_layout>::value &&
1795 std::is_same<typename lhs_traits::memory_space,
1796 typename rhs_traits::memory_space>::value &&
1797 unsigned(lhs_traits::rank) == unsigned(rhs_traits::rank) &&
1798 lhs.data() == rhs.data() && lhs.span() == rhs.span() &&
1799 lhs.extent(0) == rhs.extent(0) && lhs.extent(1) == rhs.extent(1) &&
1800 lhs.extent(2) == rhs.extent(2) && lhs.extent(3) == rhs.extent(3) &&
1801 lhs.extent(4) == rhs.extent(4) && lhs.extent(5) == rhs.extent(5) &&
1802 lhs.extent(6) == rhs.extent(6) && lhs.extent(7) == rhs.extent(7);
1803}
1804
1805template <class LT, class... LP, class RT, class... RP>
1806KOKKOS_INLINE_FUNCTION bool operator!=(const View<LT, LP...>& lhs,
1807 const View<RT, RP...>& rhs) {
1808 return !(operator==(lhs, rhs));
1809}
1810
1811} /* namespace Kokkos */
1812
1813//----------------------------------------------------------------------------
1814//----------------------------------------------------------------------------
1815
1816namespace Kokkos {
1817namespace Impl {
1818
1819inline void shared_allocation_tracking_disable() {
1820 Kokkos::Impl::SharedAllocationRecord<void, void>::tracking_disable();
1821}
1822
1823inline void shared_allocation_tracking_enable() {
1824 Kokkos::Impl::SharedAllocationRecord<void, void>::tracking_enable();
1825}
1826
1827} /* namespace Impl */
1828} /* namespace Kokkos */
1829
1830//----------------------------------------------------------------------------
1831//----------------------------------------------------------------------------
1832
1833namespace Kokkos {
1834namespace Impl {
1835
1836template <class Specialize, typename A, typename B>
1837struct CommonViewValueType;
1838
1839template <typename A, typename B>
1840struct CommonViewValueType<void, A, B> {
1841 using value_type = std::common_type_t<A, B>;
1842};
1843
1844template <class Specialize, class ValueType>
1845struct CommonViewAllocProp;
1846
1847template <class ValueType>
1848struct CommonViewAllocProp<void, ValueType> {
1849 using value_type = ValueType;
1850 using scalar_array_type = ValueType;
1851
1852 template <class... Views>
1853 KOKKOS_INLINE_FUNCTION CommonViewAllocProp(const Views&...) {}
1854};
1855
1856template <class... Views>
1857struct DeduceCommonViewAllocProp;
1858
1859// Base case must provide types for:
1860// 1. specialize 2. value_type 3. is_view 4. prop_type
1861template <class FirstView>
1862struct DeduceCommonViewAllocProp<FirstView> {
1863 using specialize = typename FirstView::traits::specialize;
1864
1865 using value_type = typename FirstView::traits::value_type;
1866
1867 enum : bool { is_view = is_view<FirstView>::value };
1868
1869 using prop_type = CommonViewAllocProp<specialize, value_type>;
1870};
1871
1872template <class FirstView, class... NextViews>
1873struct DeduceCommonViewAllocProp<FirstView, NextViews...> {
1874 using NextTraits = DeduceCommonViewAllocProp<NextViews...>;
1875
1876 using first_specialize = typename FirstView::traits::specialize;
1877 using first_value_type = typename FirstView::traits::value_type;
1878
1879 enum : bool { first_is_view = is_view<FirstView>::value };
1880
1881 using next_specialize = typename NextTraits::specialize;
1882 using next_value_type = typename NextTraits::value_type;
1883
1884 enum : bool { next_is_view = NextTraits::is_view };
1885
1886 // common types
1887
1888 // determine specialize type
1889 // if first and next specialize differ, but are not the same specialize, error
1890 // out
1891 static_assert(!(!std::is_same<first_specialize, next_specialize>::value &&
1892 !std::is_void<first_specialize>::value &&
1893 !std::is_void<next_specialize>::value),
1894 "Kokkos DeduceCommonViewAllocProp ERROR: Only one non-void "
1895 "specialize trait allowed");
1896
1897 // otherwise choose non-void specialize if either/both are non-void
1898 using specialize = std::conditional_t<
1899 std::is_same<first_specialize, next_specialize>::value, first_specialize,
1900 std::conditional_t<(std::is_void<first_specialize>::value &&
1901 !std::is_void<next_specialize>::value),
1902 next_specialize, first_specialize>>;
1903
1904 using value_type = typename CommonViewValueType<specialize, first_value_type,
1905 next_value_type>::value_type;
1906
1907 enum : bool { is_view = (first_is_view && next_is_view) };
1908
1909 using prop_type = CommonViewAllocProp<specialize, value_type>;
1910};
1911
1912} // end namespace Impl
1913
1914template <class... Views>
1915using DeducedCommonPropsType =
1916 typename Impl::DeduceCommonViewAllocProp<Views...>::prop_type;
1917
1918// This function is required in certain scenarios where users customize
1919// Kokkos View internals. One example are dynamic length embedded ensemble
1920// types. The function is used to propagate necessary information
1921// (like the ensemble size) when creating new views.
1922// However, most of the time it is called with a single view.
1923// Furthermore, the propagated information is not just for view allocations.
1924// From what I can tell, the type of functionality provided by
1925// common_view_alloc_prop is the equivalent of propagating accessors in mdspan,
1926// a mechanism we will eventually use to replace this clunky approach here, when
1927// we are finally mdspan based.
1928// TODO: get rid of this when we have mdspan
1929template <class... Views>
1930KOKKOS_INLINE_FUNCTION DeducedCommonPropsType<Views...> common_view_alloc_prop(
1931 Views const&... views) {
1932 return DeducedCommonPropsType<Views...>(views...);
1933}
1934
1935} // namespace Kokkos
1936
1937#include <impl/Kokkos_ViewUniformType.hpp>
1938#include <impl/Kokkos_Atomic_View.hpp>
1939
1940//----------------------------------------------------------------------------
1941//----------------------------------------------------------------------------
1942
1943#endif /* #ifndef KOKKOS_VIEW_HPP */
View
View to an array of data.
typename Impl::ViewUniformType< View, 0 >::type uniform_type
Unified types.
KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t< std::is_integral< iType >::value, size_t > extent(const iType &r) const noexcept
rank() to be implemented
Traits class for accessing attributes of a View.