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