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
23#ifndef KOKKOS_VIEW_HPP
24#define KOKKOS_VIEW_HPP
25
26#include <Kokkos_Macros.hpp>
27#ifdef KOKKOS_ENABLE_IMPL_MDSPAN
28#include <View/Kokkos_BasicView.hpp>
29#endif
30#ifdef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
31#include <View/Kokkos_ViewLegacy.hpp>
32#else
33
34#include <View/Kokkos_ViewTraits.hpp>
35#include <Kokkos_MemoryTraits.hpp>
36
37// FIXME: This will eventually be removed
38namespace Kokkos::Impl {
39template <class, class...>
40class ViewMapping;
41}
42#include <View/Kokkos_ViewMapping.hpp>
43#include <Kokkos_MinMax.hpp>
44
45// Class to provide a uniform type
46namespace Kokkos {
47namespace Impl {
48template <class ViewType, int Traits>
49struct ViewUniformType;
50
51template <class ParentView>
52struct ViewTracker;
53} /* namespace Impl */
54
55template <class T1, class T2>
56struct is_always_assignable_impl;
57
58template <class... ViewTDst, class... ViewTSrc>
59struct is_always_assignable_impl<Kokkos::View<ViewTDst...>,
60 Kokkos::View<ViewTSrc...> > {
61 using dst_mdspan = typename Kokkos::View<ViewTDst...>::mdspan_type;
62 using src_mdspan = typename Kokkos::View<ViewTSrc...>::mdspan_type;
63
64 constexpr static bool value =
65 std::is_constructible_v<dst_mdspan, src_mdspan> &&
66 static_cast<int>(Kokkos::View<ViewTDst...>::rank_dynamic) >=
67 static_cast<int>(Kokkos::View<ViewTSrc...>::rank_dynamic);
68};
69
70template <class View1, class View2>
71using is_always_assignable = is_always_assignable_impl<
72 std::remove_reference_t<View1>,
73 std::remove_const_t<std::remove_reference_t<View2> > >;
74
75template <class T1, class T2>
76inline constexpr bool is_always_assignable_v =
77 is_always_assignable<T1, T2>::value;
78
79template <class... ViewTDst, class... ViewTSrc>
80constexpr bool is_assignable(const Kokkos::View<ViewTDst...>& dst,
81 const Kokkos::View<ViewTSrc...>& src) {
82 using dst_mdspan = typename Kokkos::View<ViewTDst...>::mdspan_type;
83 using src_mdspan = typename Kokkos::View<ViewTSrc...>::mdspan_type;
84
85 return is_always_assignable_v<Kokkos::View<ViewTDst...>,
86 Kokkos::View<ViewTSrc...> > ||
87 (std::is_constructible_v<dst_mdspan, src_mdspan> &&
88 ((dst_mdspan::rank_dynamic() >= 1) ||
89 (dst.static_extent(0) == src.extent(0))) &&
90 ((dst_mdspan::rank_dynamic() >= 2) ||
91 (dst.static_extent(1) == src.extent(1))) &&
92 ((dst_mdspan::rank_dynamic() >= 3) ||
93 (dst.static_extent(2) == src.extent(2))) &&
94 ((dst_mdspan::rank_dynamic() >= 4) ||
95 (dst.static_extent(3) == src.extent(3))) &&
96 ((dst_mdspan::rank_dynamic() >= 5) ||
97 (dst.static_extent(4) == src.extent(4))) &&
98 ((dst_mdspan::rank_dynamic() >= 6) ||
99 (dst.static_extent(5) == src.extent(5))) &&
100 ((dst_mdspan::rank_dynamic() >= 7) ||
101 (dst.static_extent(6) == src.extent(6))) &&
102 ((dst_mdspan::rank_dynamic() == 8) ||
103 (dst.static_extent(7) == src.extent(7))));
104}
105
106namespace Impl {
107template <class... Properties>
108struct BasicViewFromTraits {
109 using view_traits = ViewTraits<Properties...>;
110 using mdspan_view_traits = MDSpanViewTraits<view_traits>;
111 using element_type = typename view_traits::value_type;
112 using extents_type = typename mdspan_view_traits::extents_type;
113 using layout_type = typename mdspan_view_traits::mdspan_layout_type;
114 using accessor_type = typename mdspan_view_traits::accessor_type;
115
116 using type =
117 BV::BasicView<element_type, extents_type, layout_type, accessor_type>;
118};
119
120// Helper function to deal with cases where the data handle is
121// not convertible to element_type* such as in Sacado.
122// An overload for our reference counted data handle is next to its
123// implementation. This one covers Unmanaged views with raw pointers.
124template <class HandleType>
125KOKKOS_INLINE_FUNCTION constexpr auto ptr_from_data_handle(
126 const HandleType& handle) {
127 // This should only be internally invoked in Kokkos with raw pointers.
128 static_assert(std::is_pointer_v<HandleType>);
129 return handle;
130}
131} // namespace Impl
132
133template <class DataType, class... Properties>
134struct ViewTraits;
135
136template <class DataType, class... Properties>
137class View;
138
139template <class>
140struct is_view : public std::false_type {};
141
142template <class D, class... P>
143struct is_view<View<D, P...> > : public std::true_type {};
144
145template <class D, class... P>
146struct is_view<const View<D, P...> > : public std::true_type {};
147
148template <class T>
149inline constexpr bool is_view_v = is_view<T>::value;
150
151template <class DataType, class... Properties>
152class View : public Impl::BasicViewFromTraits<DataType, Properties...>::type {
153 // We are deriving from BasicView, but need a helper to translate
154 // View template parameters to BasicView template parameters
155 private:
156 template <class, class...>
157 friend class View;
158 template <typename V>
159 friend struct Kokkos::Impl::ViewTracker;
160
161 using base_t =
162 typename Impl::BasicViewFromTraits<DataType, Properties...>::type;
163
164 public:
165 using base_t::base_t;
166
167 // typedefs originally from ViewTraits
168 using traits = ViewTraits<DataType, Properties...>;
169 using const_value_type = typename traits::const_value_type;
170 using non_const_value_type = typename traits::non_const_value_type;
171 using data_type = DataType;
172 using const_data_type = typename traits::const_data_type;
173 using non_const_data_type = typename traits::non_const_data_type;
174 using view_tracker_type = Impl::ViewTracker<View>;
175 using array_layout = typename traits::array_layout;
176 using device_type = typename traits::device_type;
177 using execution_space = typename traits::execution_space;
178 using memory_space = typename traits::memory_space;
179 using memory_traits = typename traits::memory_traits;
180 using host_mirror_space = typename traits::host_mirror_space;
181 using typename base_t::index_type;
182
183 // aliases from BasicView
184
185 // FIXME: Should be unsigned
186 // FIXME: these are overriden so that their types are identical when using
187 // BasicView or Legacy we will need to obtain these from base_t in the future
188 // and deprecate old behavior
189 using size_type = typename memory_space::size_type;
190 using value_type = typename traits::value_type;
191 // pointer_type can be different from element_type*
192 using pointer_type = decltype(Impl::ptr_from_data_handle(
193 std::declval<typename base_t::data_handle_type>()));
194
195 private:
196 using raw_allocation_value_type = std::remove_pointer_t<pointer_type>;
197
198 public:
199 using scalar_array_type = typename traits::scalar_array_type;
200 using const_scalar_array_type = typename traits::const_scalar_array_type;
201 using non_const_scalar_array_type =
202 typename traits::non_const_scalar_array_type;
203
204 // typedefs from BasicView
205 using typename base_t::mdspan_type;
206 using reference_type = typename base_t::reference;
207
208 //----------------------------------------
209 // Compatible view of array of scalar types
210 using array_type =
211 View<typename traits::scalar_array_type, typename traits::array_layout,
212 typename traits::device_type, typename traits::hooks_policy,
213 typename traits::memory_traits>;
214
215 // Compatible view of const data type
216 using const_type =
217 View<typename traits::const_data_type, typename traits::array_layout,
218 typename traits::device_type, typename traits::hooks_policy,
219 typename traits::memory_traits>;
220
221 // Compatible view of non-const data type
222 using non_const_type =
223 View<typename traits::non_const_data_type, typename traits::array_layout,
224 typename traits::device_type, typename traits::hooks_policy,
225 typename traits::memory_traits>;
226
227 // Compatible HostMirror view
228 using host_mirror_type =
229 View<typename traits::non_const_data_type, typename traits::array_layout,
230 Device<DefaultHostExecutionSpace,
231 typename traits::host_mirror_space::memory_space>,
232 typename traits::hooks_policy>;
233
234 // Compatible HostMirror view
235 using HostMirror = host_mirror_type;
236
237 // Unified types
238 using uniform_type = typename Impl::ViewUniformType<View, 0>::type;
239 using uniform_const_type =
240 typename Impl::ViewUniformType<View, 0>::const_type;
241 using uniform_runtime_type =
242 typename Impl::ViewUniformType<View, 0>::runtime_type;
243 using uniform_runtime_const_type =
244 typename Impl::ViewUniformType<View, 0>::runtime_const_type;
245 using uniform_nomemspace_type =
246 typename Impl::ViewUniformType<View, 0>::nomemspace_type;
247 using uniform_const_nomemspace_type =
248 typename Impl::ViewUniformType<View, 0>::const_nomemspace_type;
249 using uniform_runtime_nomemspace_type =
250 typename Impl::ViewUniformType<View, 0>::runtime_nomemspace_type;
251 using uniform_runtime_const_nomemspace_type =
252 typename Impl::ViewUniformType<View, 0>::runtime_const_nomemspace_type;
253
254 //----------------------------------------
255 // Domain rank and extents
256
257 static constexpr Impl::integral_constant<size_t, base_t::rank()> rank = {};
258 static constexpr Impl::integral_constant<size_t, base_t::rank_dynamic()>
259 rank_dynamic = {};
260#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
261 enum {Rank KOKKOS_DEPRECATED_WITH_COMMENT("Use rank instead.") = rank()};
262#endif
263
264 KOKKOS_INLINE_FUNCTION constexpr array_layout layout() const {
265 return Impl::array_layout_from_mapping<array_layout, mdspan_type>(
266 base_t::mapping());
267 }
268
269 KOKKOS_FUNCTION constexpr size_t stride_0() const { return stride(0); }
270 KOKKOS_FUNCTION constexpr size_t stride_1() const { return stride(1); }
271 KOKKOS_FUNCTION constexpr size_t stride_2() const { return stride(2); }
272 KOKKOS_FUNCTION constexpr size_t stride_3() const { return stride(3); }
273 KOKKOS_FUNCTION constexpr size_t stride_4() const { return stride(4); }
274 KOKKOS_FUNCTION constexpr size_t stride_5() const { return stride(5); }
275 KOKKOS_FUNCTION constexpr size_t stride_6() const { return stride(6); }
276 KOKKOS_FUNCTION constexpr size_t stride_7() const { return stride(7); }
277
278 template <typename iType>
279 KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<std::is_integral_v<iType>,
280 size_t>
281 stride(iType r) const {
282 // base class doesn't have constraint
283 // FIXME: Eventually we need to deprecate this behavior and just use
284 // BasicView implementation
285#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
286 using LayoutType = typename mdspan_type::layout_type;
287 if (r >= static_cast<iType>(rank())) {
288 if constexpr (rank() == 0) return 1;
289 if constexpr (std::is_same_v<LayoutType, layout_right> ||
290 Impl::IsLayoutRightPadded<LayoutType>::value) {
291 return 1;
292 }
293 if constexpr (std::is_same_v<LayoutType, layout_left> ||
294 Impl::IsLayoutLeftPadded<LayoutType>::value) {
295 return base_t::stride(rank() - 1) * extent(rank() - 1);
296 }
297 if constexpr (std::is_same_v<LayoutType, layout_stride>) {
298 return 0;
299 }
300 }
301#else
302 KOKKOS_ASSERT(r < static_cast<iType>(rank()));
303#endif
304 return base_t::stride(r);
305 }
306
307 template <typename iType>
308 KOKKOS_INLINE_FUNCTION void stride([[maybe_unused]] iType* const s) const {
309 if constexpr (rank() > 0) {
310 size_t max_stride = 0;
311 size_t max_stride_idx = 0;
312 for (size_t r = 0; r < rank(); r++) {
313 s[r] = base_t::stride(r);
314 if (s[r] > static_cast<iType>(max_stride)) {
315 max_stride = s[r];
316 max_stride_idx = r;
317 }
318 }
319 s[rank()] = max_stride * base_t::extent(max_stride_idx);
320 }
321 }
322
323 //----------------------------------------
324 // Range span is the span which contains all members.
325
326 static constexpr auto reference_type_is_lvalue_reference =
327 std::is_lvalue_reference_v<reference_type>;
328
329 KOKKOS_INLINE_FUNCTION constexpr size_t span() const {
330 return base_t::mapping().required_span_size();
331 }
332 KOKKOS_INLINE_FUNCTION bool span_is_contiguous() const {
333 return base_t::is_exhaustive();
334 }
335 KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
336 return data() != nullptr;
337 }
338 KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
339 return Impl::ptr_from_data_handle(base_t::data_handle());
340 }
341
342 KOKKOS_INLINE_FUNCTION constexpr int extent_int(size_t r) const {
343 return static_cast<int>(base_t::extent(r));
344 }
345 //----------------------------------------
346 // Allow specializations to query their specialized map
347
348 KOKKOS_INLINE_FUNCTION
349 auto impl_map() const {
350 using map_type =
351 Kokkos::Impl::ViewMapping<traits, typename traits::specialize>;
352 return map_type(Kokkos::view_wrap(data()), layout());
353 }
354
355 KOKKOS_INLINE_FUNCTION
356 const Kokkos::Impl::SharedAllocationTracker& impl_track() const {
357 if constexpr (traits::is_managed) {
358 return base_t::data_handle().tracker();
359 } else {
360 static const Kokkos::Impl::SharedAllocationTracker empty_tracker = {};
361 return empty_tracker;
362 }
363 }
364 //----------------------------------------
365 // Operators always provided by View
366
367 template <class OtherIndexType>
368 KOKKOS_FUNCTION constexpr reference_type operator[](
369 const OtherIndexType& idx) const {
370 return base_t::operator()(idx);
371 }
372
373 private:
374
375#ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
376 template <typename... Is>
377 static KOKKOS_FUNCTION void check_access_member_function_valid_args(
378 Is... is) {
379 // cast to int to work around pointless comparison of unsigned to 0 warning
380 static_assert(static_cast<int>(sizeof...(Is)) <=
381 static_cast<int>(8 - rank));
382 static_assert(Kokkos::Impl::are_integral<Is...>::value);
383 if (!((is == static_cast<Is>(0)) && ... && true))
384 Kokkos::abort("Extra arguments to Kokkos::access must be zero");
385 }
386#else
387 template <typename... Is>
388 static KOKKOS_FUNCTION void check_access_member_function_valid_args(Is...) {
389 // cast to int to work around pointless comparison of unsigned to 0 warning
390 static_assert(static_cast<int>(sizeof...(Is)) <=
391 static_cast<int>(8 - rank));
392 static_assert(Kokkos::Impl::are_integral<Is...>::value);
393 }
394#endif
395
396 public:
397 //------------------------------
398 // Rank 0
399
400 template <typename... Is>
401 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
402 (Kokkos::Impl::always_true<Is...>::value && (0 == rank)), reference_type>
403 access(Is... extra) const {
404 check_access_member_function_valid_args(extra...);
405 return base_t::operator()();
406 }
407
408 //------------------------------
409 // Rank 1
410
411 template <typename I0, typename... Is>
412 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
413 (Kokkos::Impl::always_true<I0, Is...>::value && (1 == rank)),
414 reference_type>
415 access(I0 i0, Is... extra) const {
416 check_access_member_function_valid_args(extra...);
417 return base_t::operator()(i0);
418 }
419
420 //------------------------------
421 // Rank 2
422
423 template <typename I0, typename I1, typename... Is>
424 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
425 (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == rank)),
426 reference_type>
427 access(I0 i0, I1 i1, Is... extra) const {
428 check_access_member_function_valid_args(extra...);
429 return base_t::operator()(i0, i1);
430 }
431
432 //------------------------------
433 // Rank 3
434
435 template <typename I0, typename I1, typename I2, typename... Is>
436 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
437 (Kokkos::Impl::always_true<I0, I1, I2, Is...>::value && (3 == rank)),
438 reference_type>
439 access(I0 i0, I1 i1, I2 i2, Is... extra) const {
440 check_access_member_function_valid_args(extra...);
441 return base_t::operator()(i0, i1, i2);
442 }
443
444 //------------------------------
445 // Rank 4
446
447 template <typename I0, typename I1, typename I2, typename I3, typename... Is>
448 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
449 (Kokkos::Impl::always_true<I0, I1, I2, I3, Is...>::value && (4 == rank)),
450 reference_type>
451 access(I0 i0, I1 i1, I2 i2, I3 i3, Is... extra) const {
452 check_access_member_function_valid_args(extra...);
453 return base_t::operator()(i0, i1, i2, i3);
454 }
455
456 //------------------------------
457 // Rank 5
458
459 template <typename I0, typename I1, typename I2, typename I3, typename I4,
460 typename... Is>
461 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
462 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, Is...>::value &&
463 (5 == rank)),
464 reference_type>
465 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, Is... extra) const {
466 check_access_member_function_valid_args(extra...);
467 return base_t::operator()(i0, i1, i2, i3, i4);
468 }
469
470 //------------------------------
471 // Rank 6
472
473 template <typename I0, typename I1, typename I2, typename I3, typename I4,
474 typename I5, typename... Is>
475 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
476 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, Is...>::value &&
477 (6 == rank)),
478 reference_type>
479 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, Is... extra) const {
480 check_access_member_function_valid_args(extra...);
481 return base_t::operator()(i0, i1, i2, i3, i4, i5);
482 }
483
484 //------------------------------
485 // Rank 7
486
487 template <typename I0, typename I1, typename I2, typename I3, typename I4,
488 typename I5, typename I6, typename... Is>
489 KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
490 (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6, Is...>::value &&
491 (7 == rank)),
492 reference_type>
493 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, Is... extra) const {
494 check_access_member_function_valid_args(extra...);
495 return base_t::operator()(i0, i1, i2, i3, i4, i5, i6);
496 }
497
498 //------------------------------
499 // Rank 8
500
501 template <typename I0, typename I1, typename I2, typename I3, typename I4,
502 typename I5, typename I6, typename I7, typename... Is>
503 KOKKOS_FORCEINLINE_FUNCTION
504 std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6,
505 I7, Is...>::value &&
506 (8 == rank)),
507 reference_type>
508 access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, I7 i7,
509 Is... extra) const {
510 check_access_member_function_valid_args(extra...);
511 return base_t::operator()(i0, i1, i2, i3, i4, i5, i6, i7);
512 }
513
514 //----------------------------------------
515 // Standard destructor, constructors, and assignment operators
516
517 KOKKOS_DEFAULTED_FUNCTION
518 ~View() = default;
519
520 KOKKOS_DEFAULTED_FUNCTION
521 View() = default;
522
523 KOKKOS_DEFAULTED_FUNCTION
524 View(const View& other) = default;
525
526 KOKKOS_DEFAULTED_FUNCTION
527 View(View&& other) = default;
528
529 KOKKOS_DEFAULTED_FUNCTION
530 View& operator=(const View& other) = default;
531
532 KOKKOS_DEFAULTED_FUNCTION
533 View& operator=(View&& other) = default;
534
535 KOKKOS_FUNCTION
536 View(typename base_t::data_handle_type p,
537 const typename base_t::mapping_type& m)
538 : base_t(p, m) {}
539
540 //----------------------------------------
541 // Compatible view copy constructor and assignment
542 // may assign unmanaged from managed.
543
544 template <class OtherT, class... OtherArgs>
545 // requires(std::is_constructible_v<
546 // mdspan_type, typename View<OtherT, OtherArgs...>::mdspan_type>)
547 KOKKOS_INLINE_FUNCTION View(
548 const View<OtherT, OtherArgs...>& other,
549 std::enable_if_t<
550 std::is_constructible_v<
551 mdspan_type, typename View<OtherT, OtherArgs...>::mdspan_type>,
552 void*> = nullptr)
553 : base_t(static_cast<typename mdspan_type::data_handle_type>(
554 other.data_handle()),
555 static_cast<typename mdspan_type::mapping_type>(other.mapping()),
556 static_cast<typename mdspan_type::accessor_type>(
557 other.accessor())) {
558 base_t::check_basic_view_constructibility(other.mapping());
559 }
560
561 //----------------------------------------
562 // Compatible subview constructor
563 // may assign unmanaged from managed.
564
565 template <class RT, class... RP, class Arg0, class... Args>
566 KOKKOS_INLINE_FUNCTION View(const View<RT, RP...>& src_view, const Arg0 arg0,
567 Args... args)
568 : base_t(Impl::subview_ctor_tag, src_view, arg0, args...) {}
569
570 //----------------------------------------
571 // Allocation according to allocation properties and array layout
572
573 template <class... P>
574 explicit View(const Impl::ViewCtorProp<P...>& arg_prop,
575 std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer,
576 const typename traits::array_layout&>
577 arg_layout)
578 : base_t(
579 arg_prop,
580 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
581 arg_layout)) {
582 static_assert(traits::is_managed,
583 "Can't construct managed View with unmanaged memory trait!");
584 }
585
586 template <class... P>
587 KOKKOS_FUNCTION explicit View(
588 const Impl::ViewCtorProp<P...>& arg_prop,
589 std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer,
590 const typename traits::array_layout&>
591 arg_layout)
592 : base_t(
593 arg_prop,
594 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
595 arg_layout)) {}
596
597#ifdef KOKKOS_ENABLE_CXX17
598 template <class Layout>
599 KOKKOS_FUNCTION explicit View(
600 const typename base_t::data_handle_type& handle, const Layout& arg_layout,
601 std::enable_if_t<
602 (std::is_same_v<Layout, LayoutStride> &&
603 std::is_same_v<typename base_t::layout_type, layout_stride>) ||
604 (std::is_same_v<Layout, LayoutLeft> &&
605 std::is_same_v<typename base_t::layout_type, layout_left>) ||
606 (std::is_same_v<Layout, LayoutLeft> &&
607 std::is_same_v<typename base_t::layout_type,
608 Experimental::layout_left_padded<> >) ||
609 (std::is_same_v<Layout, LayoutRight> &&
610 std::is_same_v<typename base_t::layout_type, layout_right>) ||
611 (std::is_same_v<Layout, LayoutRight> &&
612 std::is_same_v<typename base_t::layout_type,
613 Experimental::layout_right_padded<> >),
614 void*> = nullptr)
615 : base_t(
616 handle,
617 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
618 arg_layout)) {}
619#else
620 // Constructors from legacy layouts when using Views of the new layouts
621 // LayoutLeft -> layout_left, layout_left_padded
622 // LayoutRight -> layout_right, layout_right_padded
623 // LayoutStride -> layout_stride
624 KOKKOS_FUNCTION
625 explicit View(const typename base_t::data_handle_type& handle,
626 const LayoutStride& arg_layout)
627 requires(std::is_same_v<typename base_t::layout_type, layout_stride>)
628 : base_t(
629 handle,
630 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
631 arg_layout)) {}
632
633 KOKKOS_FUNCTION
634 explicit View(const typename base_t::data_handle_type& handle,
635 const LayoutLeft& arg_layout)
636 requires(std::is_same_v<typename base_t::layout_type,
637 Experimental::layout_left_padded<> >)
638 : base_t(
639 handle,
640 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
641 arg_layout)) {}
642
643 KOKKOS_FUNCTION
644 explicit View(const typename base_t::data_handle_type& handle,
645 const LayoutRight& arg_layout)
646 requires(std::is_same_v<typename base_t::layout_type,
647 Experimental::layout_right_padded<> >)
648 : base_t(
649 handle,
650 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
651 arg_layout)) {}
652
653 KOKKOS_FUNCTION
654 explicit View(const typename base_t::data_handle_type& handle,
655 const LayoutLeft& arg_layout)
656 requires(std::is_same_v<typename base_t::layout_type, layout_left>)
657 : base_t(
658 handle,
659 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
660 arg_layout)) {}
661
662 KOKKOS_FUNCTION
663 explicit View(const typename base_t::data_handle_type& handle,
664 const LayoutRight& arg_layout)
665 requires(std::is_same_v<typename base_t::layout_type, layout_right>)
666 : base_t(
667 handle,
668 Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
669 arg_layout)) {}
670#endif
671
672#ifndef KOKKOS_ENABLE_CXX17
673 template <class P, class... Args>
674 requires(!std::is_null_pointer_v<P> &&
675 std::is_constructible_v<typename base_t::data_handle_type, P> &&
676 sizeof...(Args) != rank() + 1)
677 KOKKOS_FUNCTION View(P ptr_, Args... args)
678 : View(Kokkos::view_wrap(static_cast<pointer_type>(ptr_)), args...) {}
679
680 // Special function to be preferred over the above for string literals
681 // when pointer type is char*
682 template <class L, class... Args>
683 requires(std::is_same_v<pointer_type, char*> &&
684 std::is_same_v<const char*, L>)
685 explicit View(L label, Args... args)
686 : View(Kokkos::view_alloc(std::string(label)), args...) {}
687
688 // Special function to be preferred over the above for passing in 0, NULL or
689 // nullptr when pointer type is char*
690 template <class... Args>
691 KOKKOS_FUNCTION explicit View(std::nullptr_t, Args... args)
692 : View(Kokkos::view_wrap(pointer_type(nullptr)), args...) {}
693#else
694 // FIXME: The std::is_null_pointer_v<P> condition is to workaround a GCC8 bug
695 // in overload resolution
696 // FIXME: why does modernize-type-traits have a false positive here?
697 // NOLINTBEGIN(modernize-type-traits)
698 template <class P, class... Args,
699 std::enable_if_t<!std::is_null_pointer_v<P> &&
700 std::is_constructible_v<
701 typename base_t::data_handle_type, P> &&
702 sizeof...(Args) != rank() + 1,
703 size_t> = 0ul>
704 // NOLINTEND(modernize-type-traits)
705 KOKKOS_FUNCTION View(P ptr_, Args... args)
706 : View(Kokkos::view_wrap(static_cast<pointer_type>(ptr_)), args...) {}
707
708 // Special function to be preferred over the above for string literals
709 // when pointer type is char*
710 // The typename P = pointer_type is a workaround for an nvcc 11.0 bug
711 // where the compiler performs substitution earlier when the class is
712 // instantiated instead of at function instantiation and therefore errors out
713 // on these enable_ifs
714 // FIXME: why does modernize-type-traits have a false positive here?
715 // NOLINTBEGIN(modernize-type-traits)
716 template <class L, class... Args, typename P = pointer_type,
717 std::enable_if_t<(std::is_same_v<P, char*> &&
718 std::is_same_v<const char*, L>),
719 size_t> = 0ul>
720 // NOLINTEND(modernize-type-traits)
721 explicit View(L label, Args... args)
722 : View(Kokkos::view_alloc(std::string(label)), args...) {}
723
724 // Special function to be preferred over the above for passing in 0, NULL or
725 // nullptr when pointer type is char*
726 template <class... Args>
727 KOKKOS_FUNCTION explicit View(std::nullptr_t, Args... args)
728 : View(Kokkos::view_wrap(pointer_type(nullptr)), args...) {}
729#endif
730
731 // FIXME: Constructor which allows always 8 sizes should be deprecated
732 template <class... P>
733 explicit View(
734 const Impl::ViewCtorProp<P...>& arg_prop,
735 std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer, const size_t>
736 arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
737 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
738 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
739 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
740 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
741 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
742 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
743 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
744 : base_t(arg_prop,
745 Impl::mapping_from_ctor_and_8sizes<
746 typename mdspan_type::mapping_type, sizeof(value_type)>(
747 arg_prop, arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
748 arg_N6, arg_N7)) {
749#ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
750 if constexpr (std::is_same_v<typename traits::array_layout,
752 std::is_same_v<typename traits::array_layout,
754 std::is_same_v<typename traits::array_layout,
756 auto prop_copy = Impl::with_properties_if_unset(arg_prop, std::string{});
757 const std::string& alloc_name =
758 Impl::get_property<Impl::LabelTag>(prop_copy);
759
760 Impl::runtime_check_rank(*this, !traits::impl_is_customized, arg_N0,
761 arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
762 arg_N7, alloc_name.c_str());
763 }
764#endif
765 static_assert(traits::array_layout::is_extent_constructible,
766 "Layout is not constructible from extent arguments. Use "
767 "overload taking a layout object instead.");
768 static_assert(traits::is_managed,
769 "Can't construct managed View with unmanaged memory trait!");
770 }
771
772 template <class... P>
773 KOKKOS_FUNCTION explicit View(
774 const Impl::ViewCtorProp<P...>& arg_prop,
775 std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer, const size_t>
776 arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
777 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
778 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
779 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
780 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
781 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
782 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
783 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
784 : base_t(arg_prop,
785 Impl::mapping_from_ctor_and_8sizes<
786 typename mdspan_type::mapping_type, sizeof(value_type)>(
787 arg_prop, arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
788 arg_N6, arg_N7)) {
789#ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
790 if constexpr (std::is_same_v<typename traits::array_layout,
792 std::is_same_v<typename traits::array_layout,
794 std::is_same_v<typename traits::array_layout,
796 Impl::runtime_check_rank(*this, !traits::impl_is_customized, arg_N0,
797 arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
798 arg_N7, "UNMANAGED");
799 }
800#endif
801 static_assert(traits::array_layout::is_extent_constructible,
802 "Layout is not constructible from extent arguments. Use "
803 "overload taking a layout object instead.");
804 }
805
806 // Allocate with label and layout
807 template <typename Label>
808 explicit View(
809 const Label& arg_label,
810 std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value,
811 typename traits::array_layout> const& arg_layout)
812 : View(Impl::ViewCtorProp<std::string>(arg_label), arg_layout) {}
813
814#ifdef KOKKOS_COMPILER_MSVC // FIXME_MSVC
815 // MSVC had pack expansion issues with the condition inside the enable_if
816 private:
817 template <class... Args>
818 static constexpr bool msvc_workaround_ctor_condition_1() {
819 size_t num_args = sizeof...(Args);
820 bool are_constructible =
821 (std::is_constructible_v<size_t, Args> && ... && true);
822 return (num_args != rank() + 1) && are_constructible;
823 }
824
825 public:
826#endif
827
828 template <class... Args>
829 View(std::enable_if_t<
830#ifndef KOKKOS_COMPILER_MSVC
831 ((sizeof...(Args)) != rank() + 1) &&
832 (std::is_constructible_v<size_t, Args> && ... && true),
833#else
834 msvc_workaround_ctor_condition_1<Args...>(),
835#endif
836 const std::string&>
837 arg_label,
838 const Args... args)
839#ifdef KOKKOS_COMPILER_INTEL_LLVM // FIXME_INTEL
840 // Eventually we want to get rid of the array_layout thing entirely.
841 // For now this avoids a bug in the intel compiler 2024.2, and 2025 tested
842 // that only happens with O2 or higher and makes some extents not being
843 // set See https://github.com/kokkos/kokkos/pull/8202
844 : View(Impl::ViewCtorProp<std::string>(arg_label),
845 typename traits::array_layout(args...)) {
846#else
847 : View(Impl::ViewCtorProp<std::string>(arg_label), args...) {
848#endif
849 }
850
851 private:
852 // Special thing for Sacado taking rank()+1 integers, where the last integer
853 // is the FAD dimension
854 template <class... Args, size_t... Idx>
855 static auto view_alloc_from_label_and_integrals(std::true_type,
856 const std::string& arg_label,
857 std::index_sequence<Idx...>,
858 Args... args) {
859 return view_alloc(arg_label, Impl::AccessorArg_t{static_cast<size_t>(
860 ((Idx == rank() ? args : 0) + ... + 0))});
861 }
862
863 template <class... Args, size_t... Idx>
864 static auto view_alloc_from_label_and_integrals(std::false_type,
865 const std::string& arg_label,
866 std::index_sequence<Idx...>,
867 Args...) {
868 return view_alloc(arg_label);
869 }
870
871#ifdef KOKKOS_COMPILER_MSVC // FIXME_MSVC
872 // Same as above but checking for num_args equal to rank()+1
873 template <class... Args>
874 static constexpr bool msvc_workaround_ctor_condition_2() {
875 size_t num_args = sizeof...(Args);
876 bool are_constructible =
877 (std::is_constructible_v<size_t, Args> && ... && true);
878 return (num_args == rank() + 1) && are_constructible;
879 }
880#endif
881
882 public:
883 template <class... Args>
884 View(std::enable_if_t<
885#ifndef KOKKOS_COMPILER_MSVC
886 ((sizeof...(Args)) == rank() + 1) &&
887 (std::is_constructible_v<size_t, Args> && ... && true),
888#else
889 msvc_workaround_ctor_condition_2<Args...>(),
890#endif
891 const std::string&>
892 arg_label,
893 const Args... args)
894 : View(
895 view_alloc_from_label_and_integrals(
896 std::bool_constant<traits::impl_is_customized>(), arg_label,
897 std::make_index_sequence<sizeof...(Args)>(), args...),
898#ifdef KOKKOS_COMPILER_INTEL_LLVM // FIXME_INTEL
899 // Eventually we want to get rid of the array_layout thing entirely.
900 // For now this avoids a bug in the intel compiler 2024.2, and 2025
901 // tested that only happens with O2 or higher and makes some extents
902 // not being set See https://github.com/kokkos/kokkos/pull/8202
903 typename traits::array_layout(args...)) {
904#else
905 args...) {
906#endif
907 }
908
909 template <class... Args>
910 View(std::enable_if_t<
911#ifndef KOKKOS_COMPILER_MSVC
912 ((sizeof...(Args)) == rank() + 1) &&
913 (std::is_constructible_v<size_t, Args> && ... && true),
914#else
915 msvc_workaround_ctor_condition_2<Args...>(),
916#endif
917 const pointer_type&>
918 arg_ptr,
919 const Args... args)
920 : View(
921 Kokkos::view_wrap(arg_ptr,
922 Kokkos::Impl::AccessorArg_t{
923 Kokkos::Array<size_t, sizeof...(Args)>{
924 static_cast<size_t>(args)...}[rank()]}),
925#ifdef KOKKOS_COMPILER_INTEL_LLVM // FIXME_INTEL
926 // Eventually we want to get rid of the array_layout thing entirely.
927 // For now this avoids a bug in the intel compiler 2024.2, and 2025
928 // tested that only happens with O2 or higher and makes some extents
929 // not being set See https://github.com/kokkos/kokkos/pull/8202
930 typename traits::array_layout(args...)) {
931#else
932 args...) {
933#endif
934 }
935
936 //----------------------------------------
937 // Memory span required to wrap these dimensions.
938 KOKKOS_FUNCTION
939 static constexpr size_t required_allocation_size(
940 typename traits::array_layout const& layout) {
941 return Impl::mapping_from_array_layout<typename base_t::mapping_type>(
942 layout)
943 .required_span_size() *
944 sizeof(raw_allocation_value_type);
945 }
946
947 KOKKOS_FUNCTION
948 static constexpr size_t required_allocation_size(
949 const size_t arg_N0 = 0, const size_t arg_N1 = 0, const size_t arg_N2 = 0,
950 const size_t arg_N3 = 0, const size_t arg_N4 = 0, const size_t arg_N5 = 0,
951 const size_t arg_N6 = 0, const size_t arg_N7 = 0) {
952 static_assert(traits::array_layout::is_extent_constructible,
953 "Layout is not constructible from extent arguments. Use "
954 "overload taking a layout object instead.");
955 return required_allocation_size(typename traits::array_layout(
956 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
957 }
958
959 //----------------------------------------
960 // Shared scratch memory constructor
961
962 static KOKKOS_INLINE_FUNCTION size_t
963 shmem_size(const size_t arg_N0 = KOKKOS_INVALID_INDEX,
964 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
965 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
966 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
967 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
968 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
969 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
970 const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
971 static_assert(traits::array_layout::is_extent_constructible,
972 "Layout is not constructible from extent arguments. Use "
973 "overload taking a layout object instead.");
974 const size_t num_passed_args = Impl::count_valid_integers(
975 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7);
976
977 // Special case to cover sacado which passes in an extra integer
978 if (traits::impl_is_customized && num_passed_args == rank_dynamic + 1) {
979 size_t extra_dim = 0;
980 switch (rank_dynamic) {
981 case 0: extra_dim = arg_N0; break;
982 case 1: extra_dim = arg_N1; break;
983 case 2: extra_dim = arg_N2; break;
984 case 3: extra_dim = arg_N3; break;
985 case 4: extra_dim = arg_N4; break;
986 case 5: extra_dim = arg_N5; break;
987 case 6: extra_dim = arg_N6; break;
988 case 7: extra_dim = arg_N7; break;
989 default:
990 Kokkos::abort("This can't happen: rank_dynamic is smaller than 8");
991 }
992 return View::shmem_size(
993 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
994 arg_N5, arg_N6, arg_N7),
995 extra_dim);
996 } else {
997 if (num_passed_args != rank_dynamic) {
998 Kokkos::abort(
999 "Kokkos::View::shmem_size() rank_dynamic != number of "
1000 "arguments.\n");
1001 }
1002 return View::shmem_size(
1003 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1004 arg_N5, arg_N6, arg_N7),
1005 1);
1006 }
1007 }
1008
1009 static KOKKOS_INLINE_FUNCTION size_t
1010 shmem_size(typename traits::array_layout const& arg_layout) {
1011 return shmem_size(arg_layout, 1);
1012 }
1013
1014 private:
1015 // Want to be able to align to minimum scratch alignment or sizeof or alignof
1016 // elements
1017 static constexpr size_t scratch_value_alignment = max(
1018 {sizeof(raw_allocation_value_type), alignof(raw_allocation_value_type),
1019 static_cast<size_t>(
1020 traits::execution_space::scratch_memory_space::ALIGN)});
1021
1022 static KOKKOS_INLINE_FUNCTION size_t shmem_size(
1023 typename traits::array_layout const& arg_layout, size_t extra_dim) {
1024 return Impl::mapping_from_array_layout<typename base_t::mapping_type>(
1025 arg_layout)
1026 .required_span_size() *
1027 sizeof(raw_allocation_value_type) * extra_dim +
1028 scratch_value_alignment;
1029 }
1030
1031 public:
1032 explicit KOKKOS_INLINE_FUNCTION View(
1033 const typename traits::execution_space::scratch_memory_space& arg_space,
1034 const typename traits::array_layout& arg_layout)
1035 : View(Impl::ViewCtorProp<pointer_type>(
1036 static_cast<pointer_type>(arg_space.get_shmem_aligned(
1037 Kokkos::Impl::ViewMapping<
1038 traits,
1039 typename traits::specialize>::memory_span(arg_layout),
1040 scratch_value_alignment))),
1041 arg_layout) {}
1042
1043 explicit KOKKOS_INLINE_FUNCTION View(
1044 const typename traits::execution_space::scratch_memory_space& arg_space,
1045 const size_t arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1046 const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1047 const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1048 const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1049 const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1050 const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1051 const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1052 const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1053 : View(Impl::ViewCtorProp<pointer_type>(
1054 static_cast<pointer_type>(arg_space.get_shmem_aligned(
1055 required_allocation_size(typename traits::array_layout(
1056 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
1057 arg_N7)),
1058 scratch_value_alignment))),
1059 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1060 arg_N4, arg_N5, arg_N6, arg_N7)) {
1061 static_assert(traits::array_layout::is_extent_constructible,
1062 "Layout is not constructible from extent arguments. Use "
1063 "overload taking a layout object instead.");
1064 }
1065
1066 public:
1067 //----------------------------------------
1068 // Allocation tracking properties
1069 std::string label() const {
1070 if constexpr (traits::is_managed) {
1071 return this->data_handle().get_label();
1072 } else {
1073 return "";
1074 }
1075 }
1076
1077 int use_count() const {
1078 if constexpr (traits::is_managed) {
1079 return this->data_handle().use_count();
1080 } else {
1081 return 0;
1082 }
1083 }
1084
1085 KOKKOS_FUNCTION
1086 constexpr typename base_t::index_type extent(size_t r) const noexcept {
1087 // casting to int to avoid warning for pointless comparison of unsigned
1088 // with 0
1089 if (static_cast<int>(r) >= static_cast<int>(base_t::extents_type::rank()))
1090 return 1;
1091 return base_t::extent(r);
1092 }
1093
1094 KOKKOS_FUNCTION
1095 static constexpr size_t static_extent(size_t r) noexcept {
1096 // casting to int to avoid warning for pointless comparison of unsigned
1097 // with 0
1098 if (static_cast<int>(r) >= static_cast<int>(base_t::extents_type::rank()))
1099 return 1;
1100 size_t value = base_t::extents_type::static_extent(r);
1101 return value == Kokkos::dynamic_extent ? 0 : value;
1102 }
1103};
1104
1105template <typename D, class... P>
1106KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const View<D, P...>&) {
1107 return View<D, P...>::rank();
1108}
1109
1110namespace Impl {
1111
1112template <typename ValueType, unsigned int Rank>
1113struct RankDataType {
1114 using type = typename RankDataType<ValueType, Rank - 1>::type*;
1115};
1116
1117template <typename ValueType>
1118struct RankDataType<ValueType, 0> {
1119 using type = ValueType;
1120};
1121
1122template <unsigned N, typename... Args>
1123KOKKOS_FUNCTION std::enable_if_t<
1124 N == View<Args...>::rank() &&
1125 std::is_same_v<typename ViewTraits<Args...>::specialize, void>,
1126 View<Args...> >
1127as_view_of_rank_n(View<Args...> v) {
1128 return v;
1129}
1130
1131// Placeholder implementation to compile generic code for DynRankView; should
1132// never be called
1133template <unsigned N, typename T, typename... Args>
1134KOKKOS_FUNCTION std::enable_if_t<
1135 N != View<T, Args...>::rank() &&
1136 std::is_same_v<typename ViewTraits<T, Args...>::specialize, void>,
1137 View<typename RankDataType<typename View<T, Args...>::value_type, N>::type,
1138 Args...> >
1139as_view_of_rank_n(View<T, Args...>) {
1140 Kokkos::abort("Trying to get at a View of the wrong rank");
1141 return {};
1142}
1143
1144template <typename ViewType>
1145struct ApplyToViewOfStaticRank {
1146 template <typename Function>
1147 static void apply(Function&& f, ViewType a) {
1148 f(a);
1149 }
1150};
1151
1152} // namespace Impl
1153//----------------------------------------------------------------------------
1154//----------------------------------------------------------------------------
1155
1156template <class D, class... P, class... Args>
1157KOKKOS_INLINE_FUNCTION auto subview(const View<D, P...>& src, Args... args) {
1158 static_assert(View<D, P...>::rank == sizeof...(Args),
1159 "subview requires one argument for each source View rank");
1160
1161 return typename Kokkos::Impl::ViewMapping<
1162 void /* deduce subview type from source view traits */
1163 ,
1164 typename Impl::RemoveAlignedMemoryTrait<D, P...>::type,
1165 Args...>::type(src, args...);
1166}
1167
1168#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
1169template <class MemoryTraits, class D, class... P, class... Args>
1170KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION auto subview(const View<D, P...>& src,
1171 Args... args) {
1172 static_assert(View<D, P...>::rank == sizeof...(Args),
1173 "subview requires one argument for each source View rank");
1175
1176 return typename Kokkos::Impl::ViewMapping<
1177 void /* deduce subview type from source view traits */
1178 ,
1179 typename Impl::RemoveAlignedMemoryTrait<D, P..., MemoryTraits>::type,
1180 Args...>::type(src, args...);
1181}
1182#endif
1183
1184template <class V, class... Args>
1185using Subview = decltype(subview(std::declval<V>(), std::declval<Args>()...));
1186
1187} /* namespace Kokkos */
1188
1189//----------------------------------------------------------------------------
1190//----------------------------------------------------------------------------
1191
1192namespace Kokkos {
1193
1194template <class LT, class... LP, class RT, class... RP>
1195KOKKOS_INLINE_FUNCTION bool operator==(const View<LT, LP...>& lhs,
1196 const View<RT, RP...>& rhs) {
1197 // Same data, layout, dimensions
1198 using lhs_traits = ViewTraits<LT, LP...>;
1199 using rhs_traits = ViewTraits<RT, RP...>;
1200
1201 return std::is_same_v<typename lhs_traits::const_value_type,
1202 typename rhs_traits::const_value_type> &&
1203 std::is_same_v<typename lhs_traits::array_layout,
1204 typename rhs_traits::array_layout> &&
1205 std::is_same_v<typename lhs_traits::memory_space,
1206 typename rhs_traits::memory_space> &&
1207 View<LT, LP...>::rank() == View<RT, RP...>::rank() &&
1208 lhs.data() == rhs.data() && lhs.span() == rhs.span() &&
1209 lhs.extent(0) == rhs.extent(0) && lhs.extent(1) == rhs.extent(1) &&
1210 lhs.extent(2) == rhs.extent(2) && lhs.extent(3) == rhs.extent(3) &&
1211 lhs.extent(4) == rhs.extent(4) && lhs.extent(5) == rhs.extent(5) &&
1212 lhs.extent(6) == rhs.extent(6) && lhs.extent(7) == rhs.extent(7);
1213}
1214
1215template <class LT, class... LP, class RT, class... RP>
1216KOKKOS_INLINE_FUNCTION bool operator!=(const View<LT, LP...>& lhs,
1217 const View<RT, RP...>& rhs) {
1218 return !(operator==(lhs, rhs));
1219}
1220
1221} /* namespace Kokkos */
1222
1223// FIXME: https://github.com/kokkos/kokkos/issues/7736 We may want to move these
1224// out
1225#include <View/Kokkos_ViewCommonType.hpp>
1226#include <View/Kokkos_ViewUniformType.hpp>
1227#include <View/Kokkos_ViewAtomic.hpp>
1228
1229//----------------------------------------------------------------------------
1230//----------------------------------------------------------------------------
1231
1232#endif /* KOKKOS_ENABLE_IMPL_VIEW_LEGACY */
1233#endif /* #ifndef KOKKOS_VIEW_HPP */
A thread safe view to a bitset.
ScopeGuard Some user scope issues have been identified with some Kokkos::finalize calls; ScopeGuard a...
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory.