LCOV - code coverage report
Current view: top level - build/_deps/kokkos-src/core/src/View - Kokkos_ViewMapping.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 26 57.7 %
Date: 2026-02-16 14:39:39 Functions: 6 8 75.0 %

          Line data    Source code
       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_EXPERIMENTAL_VIEW_MAPPING_HPP
      18             : #define KOKKOS_EXPERIMENTAL_VIEW_MAPPING_HPP
      19             : 
      20             : #include <cstring>
      21             : #include <type_traits>
      22             : #include <initializer_list>
      23             : 
      24             : #include <Kokkos_Core_fwd.hpp>
      25             : #include <Kokkos_DetectionIdiom.hpp>
      26             : #include <Kokkos_Pair.hpp>
      27             : #include <Kokkos_Layout.hpp>
      28             : #include <Kokkos_Extents.hpp>
      29             : #include <impl/Kokkos_Error.hpp>
      30             : #include <impl/Kokkos_Traits.hpp>
      31             : #include <View/Kokkos_ViewTracker.hpp>
      32             : #include <View/Kokkos_ViewTraits.hpp>
      33             : #include <View/Kokkos_ViewCtor.hpp>
      34             : #include <View/Kokkos_ViewAtomic.hpp>
      35             : #include <impl/Kokkos_Tools.hpp>
      36             : #include <impl/Kokkos_StringManipulation.hpp>
      37             : #include <impl/Kokkos_ZeroMemset_fwd.hpp>
      38             : #include <View/Kokkos_ViewDataAnalysis.hpp>
      39             : #include <View/Kokkos_ViewAlloc.hpp>
      40             : 
      41             : //----------------------------------------------------------------------------
      42             : //----------------------------------------------------------------------------
      43             : 
      44             : namespace Kokkos {
      45             : namespace Impl {
      46             : 
      47             : template <class T>
      48             : struct is_integral_extent_type {
      49             :   enum : bool { value = std::is_same_v<T, Kokkos::ALL_t> ? 1 : 0 };
      50             : };
      51             : 
      52             : template <class iType>
      53             : struct is_integral_extent_type<std::pair<iType, iType>> {
      54             :   enum : bool { value = std::is_integral_v<iType> ? 1 : 0 };
      55             : };
      56             : 
      57             : template <class iType>
      58             : struct is_integral_extent_type<Kokkos::pair<iType, iType>> {
      59             :   enum : bool { value = std::is_integral_v<iType> ? 1 : 0 };
      60             : };
      61             : 
      62             : // Assuming '2 == initializer_list<iType>::size()'
      63             : template <class iType>
      64             : struct is_integral_extent_type<std::initializer_list<iType>> {
      65             :   enum : bool { value = std::is_integral_v<iType> ? 1 : 0 };
      66             : };
      67             : 
      68             : template <unsigned I, class... Args>
      69             : struct is_integral_extent {
      70             :   // get_type is void when sizeof...(Args) <= I
      71             :   using type = std::remove_cv_t<std::remove_reference_t<
      72             :       typename Kokkos::Impl::get_type<I, Args...>::type>>;
      73             : 
      74             :   enum : bool { value = is_integral_extent_type<type>::value };
      75             : 
      76             :   static_assert(value || std::is_integral_v<type> || std::is_void_v<type>,
      77             :                 "subview argument must be either integral or integral extent");
      78             : };
      79             : 
      80             : // Rules for subview arguments and layouts matching
      81             : 
      82             : template <class LayoutDest, class LayoutSrc, int RankDest, int RankSrc,
      83             :           int CurrentArg, class... SubViewArgs>
      84             : struct SubviewLegalArgsCompileTime;
      85             : 
      86             : // Rules which allow LayoutLeft to LayoutLeft assignment
      87             : 
      88             : template <int RankDest, int RankSrc, int CurrentArg, class Arg,
      89             :           class... SubViewArgs>
      90             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutLeft, Kokkos::LayoutLeft,
      91             :                                    RankDest, RankSrc, CurrentArg, Arg,
      92             :                                    SubViewArgs...> {
      93             :   enum {
      94             :     value =
      95             :         (((CurrentArg == RankDest - 1) &&
      96             :           (Kokkos::Impl::is_integral_extent_type<Arg>::value)) ||
      97             :          ((CurrentArg >= RankDest) && (std::is_integral_v<Arg>)) ||
      98             :          ((CurrentArg < RankDest) && (std::is_same_v<Arg, Kokkos::ALL_t>)) ||
      99             :          ((CurrentArg == 0) &&
     100             :           (Kokkos::Impl::is_integral_extent_type<Arg>::value))) &&
     101             :         (SubviewLegalArgsCompileTime<Kokkos::LayoutLeft, Kokkos::LayoutLeft,
     102             :                                      RankDest, RankSrc, CurrentArg + 1,
     103             :                                      SubViewArgs...>::value)
     104             :   };
     105             : };
     106             : 
     107             : template <int RankDest, int RankSrc, int CurrentArg, class Arg>
     108             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutLeft, Kokkos::LayoutLeft,
     109             :                                    RankDest, RankSrc, CurrentArg, Arg> {
     110             :   enum {
     111             :     value = ((CurrentArg == RankDest - 1) || (std::is_integral_v<Arg>)) &&
     112             :             (CurrentArg == RankSrc - 1)
     113             :   };
     114             : };
     115             : 
     116             : // Rules which allow LayoutRight to LayoutRight assignment
     117             : 
     118             : template <int RankDest, int RankSrc, int CurrentArg, class Arg,
     119             :           class... SubViewArgs>
     120             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutRight, Kokkos::LayoutRight,
     121             :                                    RankDest, RankSrc, CurrentArg, Arg,
     122             :                                    SubViewArgs...> {
     123             :   enum {
     124             :     value = (((CurrentArg == RankSrc - RankDest) &&
     125             :               (Kokkos::Impl::is_integral_extent_type<Arg>::value)) ||
     126             :              ((CurrentArg < RankSrc - RankDest) && (std::is_integral_v<Arg>)) ||
     127             :              ((CurrentArg >= RankSrc - RankDest) &&
     128             :               (std::is_same_v<Arg, Kokkos::ALL_t>))) &&
     129             :             (SubviewLegalArgsCompileTime<Kokkos::LayoutRight,
     130             :                                          Kokkos::LayoutRight, RankDest, RankSrc,
     131             :                                          CurrentArg + 1, SubViewArgs...>::value)
     132             :   };
     133             : };
     134             : 
     135             : template <int RankDest, int RankSrc, int CurrentArg, class Arg>
     136             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutRight, Kokkos::LayoutRight,
     137             :                                    RankDest, RankSrc, CurrentArg, Arg> {
     138             :   enum {
     139             :     value =
     140             :         ((CurrentArg == RankSrc - 1) && (std::is_same_v<Arg, Kokkos::ALL_t>))
     141             :   };
     142             : };
     143             : 
     144             : // Rules which allow assignment to LayoutStride
     145             : 
     146             : template <int RankDest, int RankSrc, int CurrentArg, class... SubViewArgs>
     147             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutStride, Kokkos::LayoutLeft,
     148             :                                    RankDest, RankSrc, CurrentArg,
     149             :                                    SubViewArgs...> {
     150             :   enum : bool { value = true };
     151             : };
     152             : 
     153             : template <int RankDest, int RankSrc, int CurrentArg, class... SubViewArgs>
     154             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutStride, Kokkos::LayoutRight,
     155             :                                    RankDest, RankSrc, CurrentArg,
     156             :                                    SubViewArgs...> {
     157             :   enum : bool { value = true };
     158             : };
     159             : 
     160             : template <int RankDest, int RankSrc, int CurrentArg, class... SubViewArgs>
     161             : struct SubviewLegalArgsCompileTime<Kokkos::LayoutStride, Kokkos::LayoutStride,
     162             :                                    RankDest, RankSrc, CurrentArg,
     163             :                                    SubViewArgs...> {
     164             :   enum : bool { value = true };
     165             : };
     166             : 
     167             : template <unsigned DomainRank, unsigned RangeRank>
     168             : struct SubviewExtents {
     169             :  private:
     170             :   // Cannot declare zero-length arrays
     171             :   // '+' is used to silence GCC 7.2.0 -Wduplicated-branches warning when
     172             :   // RangeRank=1
     173             :   enum { InternalRangeRank = RangeRank ? RangeRank : +1u };
     174             : 
     175             :   size_t m_begin[DomainRank];
     176             :   size_t m_length[InternalRangeRank];
     177             :   unsigned m_index[InternalRangeRank];
     178             : 
     179             :   template <size_t... DimArgs>
     180             :   KOKKOS_FORCEINLINE_FUNCTION bool set(unsigned, unsigned,
     181             :                                        const ViewDimension<DimArgs...>&) {
     182             :     return true;
     183             :   }
     184             : 
     185             :   template <class T, size_t... DimArgs, class... Args>
     186             :   KOKKOS_FORCEINLINE_FUNCTION bool set(unsigned domain_rank,
     187             :                                        unsigned range_rank,
     188             :                                        const ViewDimension<DimArgs...>& dim,
     189             :                                        const T& val, Args... args) {
     190             :     const size_t v = static_cast<size_t>(val);
     191             : 
     192             :     m_begin[domain_rank] = v;
     193             : 
     194             :     return set(domain_rank + 1, range_rank, dim, args...)
     195             : #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
     196             :            && (v < dim.extent(domain_rank))
     197             : #endif
     198             :         ;
     199             :   }
     200             : 
     201             :   // ALL_t
     202             :   template <size_t... DimArgs, class... Args>
     203             :   KOKKOS_FORCEINLINE_FUNCTION bool set(unsigned domain_rank,
     204             :                                        unsigned range_rank,
     205             :                                        const ViewDimension<DimArgs...>& dim,
     206             :                                        Kokkos::ALL_t, Args... args) {
     207             :     m_begin[domain_rank] = 0;
     208             :     m_length[range_rank] = dim.extent(domain_rank);
     209             :     m_index[range_rank]  = domain_rank;
     210             : 
     211             :     return set(domain_rank + 1, range_rank + 1, dim, args...);
     212             :   }
     213             : 
     214             :   // std::pair range
     215             :   template <class T, size_t... DimArgs, class... Args>
     216             :   KOKKOS_FORCEINLINE_FUNCTION bool set(unsigned domain_rank,
     217             :                                        unsigned range_rank,
     218             :                                        const ViewDimension<DimArgs...>& dim,
     219             :                                        const std::pair<T, T>& val,
     220             :                                        Args... args) {
     221             :     const size_t b = static_cast<size_t>(val.first);
     222             :     const size_t e = static_cast<size_t>(val.second);
     223             : 
     224             :     m_begin[domain_rank] = b;
     225             :     m_length[range_rank] = e - b;
     226             :     m_index[range_rank]  = domain_rank;
     227             : 
     228             :     return set(domain_rank + 1, range_rank + 1, dim, args...)
     229             : #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
     230             :            && (e <= b + dim.extent(domain_rank))
     231             : #endif
     232             :         ;
     233             :   }
     234             : 
     235             :   // Kokkos::pair range
     236             :   template <class T, size_t... DimArgs, class... Args>
     237             :   KOKKOS_FORCEINLINE_FUNCTION bool set(unsigned domain_rank,
     238             :                                        unsigned range_rank,
     239             :                                        const ViewDimension<DimArgs...>& dim,
     240             :                                        const Kokkos::pair<T, T>& val,
     241             :                                        Args... args) {
     242             :     const size_t b = static_cast<size_t>(val.first);
     243             :     const size_t e = static_cast<size_t>(val.second);
     244             : 
     245             :     m_begin[domain_rank] = b;
     246             :     m_length[range_rank] = e - b;
     247             :     m_index[range_rank]  = domain_rank;
     248             : 
     249             :     return set(domain_rank + 1, range_rank + 1, dim, args...)
     250             : #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
     251             :            && (e <= b + dim.extent(domain_rank))
     252             : #endif
     253             :         ;
     254             :   }
     255             : 
     256             :   // { begin , end } range
     257             :   template <class T, size_t... DimArgs, class... Args>
     258             :   KOKKOS_FORCEINLINE_FUNCTION bool set(unsigned domain_rank,
     259             :                                        unsigned range_rank,
     260             :                                        const ViewDimension<DimArgs...>& dim,
     261             :                                        const std::initializer_list<T>& val,
     262             :                                        Args... args) {
     263             :     const size_t b = static_cast<size_t>(val.begin()[0]);
     264             :     const size_t e = static_cast<size_t>(val.begin()[1]);
     265             : 
     266             :     m_begin[domain_rank] = b;
     267             :     m_length[range_rank] = e - b;
     268             :     m_index[range_rank]  = domain_rank;
     269             : 
     270             :     return set(domain_rank + 1, range_rank + 1, dim, args...)
     271             : #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
     272             :            && (val.size() == 2) && (e <= b + dim.extent(domain_rank))
     273             : #endif
     274             :         ;
     275             :   }
     276             : 
     277             :   //------------------------------
     278             : 
     279             : #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
     280             : 
     281             :   template <size_t... DimArgs>
     282             :   void error(char*, int, unsigned, unsigned,
     283             :              const ViewDimension<DimArgs...>&) const {}
     284             : 
     285             :   template <class T, size_t... DimArgs, class... Args>
     286             :   void error(char* buf, int buf_len, unsigned domain_rank, unsigned range_rank,
     287             :              const ViewDimension<DimArgs...>& dim, const T& val,
     288             :              Args... args) const {
     289             :     const int n = std::min(
     290             :         buf_len,
     291             :         snprintf(buf, buf_len, " %lu < %lu %c", static_cast<unsigned long>(val),
     292             :                  static_cast<unsigned long>(dim.extent(domain_rank)),
     293             :                  int(sizeof...(Args) ? ',' : ')')));
     294             : 
     295             :     error(buf + n, buf_len - n, domain_rank + 1, range_rank, dim, args...);
     296             :   }
     297             : 
     298             :   // std::pair range
     299             :   template <size_t... DimArgs, class... Args>
     300             :   void error(char* buf, int buf_len, unsigned domain_rank, unsigned range_rank,
     301             :              const ViewDimension<DimArgs...>& dim, Kokkos::ALL_t,
     302             :              Args... args) const {
     303             :     const int n = std::min(buf_len, snprintf(buf, buf_len, " Kokkos::ALL %c",
     304             :                                              int(sizeof...(Args) ? ',' : ')')));
     305             : 
     306             :     error(buf + n, buf_len - n, domain_rank + 1, range_rank + 1, dim, args...);
     307             :   }
     308             : 
     309             :   // std::pair range
     310             :   template <class T, size_t... DimArgs, class... Args>
     311             :   void error(char* buf, int buf_len, unsigned domain_rank, unsigned range_rank,
     312             :              const ViewDimension<DimArgs...>& dim, const std::pair<T, T>& val,
     313             :              Args... args) const {
     314             :     // d <= e - b
     315             :     const int n = std::min(
     316             :         buf_len, snprintf(buf, buf_len, " %lu <= %lu - %lu %c",
     317             :                           static_cast<unsigned long>(dim.extent(domain_rank)),
     318             :                           static_cast<unsigned long>(val.second),
     319             :                           static_cast<unsigned long>(val.first),
     320             :                           int(sizeof...(Args) ? ',' : ')')));
     321             : 
     322             :     error(buf + n, buf_len - n, domain_rank + 1, range_rank + 1, dim, args...);
     323             :   }
     324             : 
     325             :   // Kokkos::pair range
     326             :   template <class T, size_t... DimArgs, class... Args>
     327             :   void error(char* buf, int buf_len, unsigned domain_rank, unsigned range_rank,
     328             :              const ViewDimension<DimArgs...>& dim,
     329             :              const Kokkos::pair<T, T>& val, Args... args) const {
     330             :     // d <= e - b
     331             :     const int n = std::min(
     332             :         buf_len, snprintf(buf, buf_len, " %lu <= %lu - %lu %c",
     333             :                           static_cast<unsigned long>(dim.extent(domain_rank)),
     334             :                           static_cast<unsigned long>(val.second),
     335             :                           static_cast<unsigned long>(val.first),
     336             :                           int(sizeof...(Args) ? ',' : ')')));
     337             : 
     338             :     error(buf + n, buf_len - n, domain_rank + 1, range_rank + 1, dim, args...);
     339             :   }
     340             : 
     341             :   // { begin , end } range
     342             :   template <class T, size_t... DimArgs, class... Args>
     343             :   void error(char* buf, int buf_len, unsigned domain_rank, unsigned range_rank,
     344             :              const ViewDimension<DimArgs...>& dim,
     345             :              const std::initializer_list<T>& val, Args... args) const {
     346             :     // d <= e - b
     347             :     int n = 0;
     348             :     if (val.size() == 2) {
     349             :       n = std::min(buf_len,
     350             :                    snprintf(buf, buf_len, " %lu <= %lu - %lu %c",
     351             :                             static_cast<unsigned long>(dim.extent(domain_rank)),
     352             :                             static_cast<unsigned long>(val.begin()[0]),
     353             :                             static_cast<unsigned long>(val.begin()[1]),
     354             :                             int(sizeof...(Args) ? ',' : ')')));
     355             :     } else {
     356             :       n = std::min(buf_len, snprintf(buf, buf_len, " { ... }.size() == %u %c",
     357             :                                      unsigned(val.size()),
     358             :                                      int(sizeof...(Args) ? ',' : ')')));
     359             :     }
     360             : 
     361             :     error(buf + n, buf_len - n, domain_rank + 1, range_rank + 1, dim, args...);
     362             :   }
     363             : 
     364             :   template <size_t... DimArgs, class... Args>
     365             :   KOKKOS_FORCEINLINE_FUNCTION void error(const ViewDimension<DimArgs...>& dim,
     366             :                                          Args... args) const {
     367             :     KOKKOS_IF_ON_HOST(
     368             :         (enum {LEN = 1024}; char buffer[LEN];
     369             : 
     370             :          const int n = snprintf(buffer, LEN, "Kokkos::subview bounds error (");
     371             :          error(buffer + n, LEN - n, 0, 0, dim, args...);
     372             : 
     373             :          Kokkos::abort(buffer);))
     374             : 
     375             :     KOKKOS_IF_ON_DEVICE(((void)dim;
     376             :                          Kokkos::abort("Kokkos::subview bounds error");
     377             :                          [](Args...) {}(args...);))
     378             :   }
     379             : 
     380             : #else
     381             : 
     382             :   template <size_t... DimArgs, class... Args>
     383             :   KOKKOS_FORCEINLINE_FUNCTION void error(const ViewDimension<DimArgs...>&,
     384             :                                          Args...) const {}
     385             : 
     386             : #endif
     387             : 
     388             :  public:
     389             :   template <size_t... DimArgs, class... Args>
     390             :   KOKKOS_INLINE_FUNCTION SubviewExtents(const ViewDimension<DimArgs...>& dim,
     391             :                                         Args... args) {
     392             :     static_assert(DomainRank == sizeof...(DimArgs));
     393             :     static_assert(DomainRank == sizeof...(Args));
     394             : 
     395             :     // Verifies that all arguments, up to 8, are integral types,
     396             :     // integral extents, or don't exist.
     397             :     static_assert(RangeRank ==
     398             :                   unsigned(is_integral_extent<0, Args...>::value) +
     399             :                       unsigned(is_integral_extent<1, Args...>::value) +
     400             :                       unsigned(is_integral_extent<2, Args...>::value) +
     401             :                       unsigned(is_integral_extent<3, Args...>::value) +
     402             :                       unsigned(is_integral_extent<4, Args...>::value) +
     403             :                       unsigned(is_integral_extent<5, Args...>::value) +
     404             :                       unsigned(is_integral_extent<6, Args...>::value) +
     405             :                       unsigned(is_integral_extent<7, Args...>::value));
     406             : 
     407             :     if (RangeRank == 0) {
     408             :       m_length[0] = 0;
     409             :       m_index[0]  = ~0u;
     410             :     }
     411             : 
     412             :     if (!set(0, 0, dim, args...)) error(dim, args...);
     413             :   }
     414             : 
     415             :   template <typename iType>
     416             :   KOKKOS_FORCEINLINE_FUNCTION constexpr size_t domain_offset(
     417             :       const iType i) const {
     418             :     return unsigned(i) < DomainRank ? m_begin[i] : 0;
     419             :   }
     420             : 
     421             :   template <typename iType>
     422             :   KOKKOS_FORCEINLINE_FUNCTION constexpr size_t range_extent(
     423             :       const iType i) const {
     424             :     return unsigned(i) < InternalRangeRank ? m_length[i] : 0;
     425             :   }
     426             : 
     427             :   template <typename iType>
     428             :   KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned range_index(
     429             :       const iType i) const {
     430             :     return unsigned(i) < InternalRangeRank ? m_index[i] : ~0u;
     431             :   }
     432             : };
     433             : 
     434             : }  // namespace Impl
     435             : }  // namespace Kokkos
     436             : 
     437             : //----------------------------------------------------------------------------
     438             : //----------------------------------------------------------------------------
     439             : 
     440             : namespace Kokkos {
     441             : namespace Impl {
     442             : //----------------------------------------------------------------------------
     443             : // LayoutLeft AND ( 1 >= rank OR 0 == rank_dynamic ) : no padding / striding
     444             : template <class Dimension>
     445             : struct ViewOffset<
     446             :     Dimension, Kokkos::LayoutLeft,
     447             :     std::enable_if_t<(1 >= Dimension::rank || 0 == Dimension::rank_dynamic)>> {
     448             :   using is_mapping_plugin = std::true_type;
     449             :   using is_regular        = std::true_type;
     450             : 
     451             :   using size_type      = size_t;
     452             :   using dimension_type = Dimension;
     453             :   using array_layout   = Kokkos::LayoutLeft;
     454             : 
     455             :   dimension_type m_dim;
     456             : 
     457             :   //----------------------------------------
     458             : 
     459             :   // rank 1
     460             :   template <typename I0>
     461             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0) const {
     462             :     return i0;
     463             :   }
     464             : 
     465             :   // rank 2
     466             :   template <typename I0, typename I1>
     467             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     468             :                                                         I1 const& i1) const {
     469             :     return i0 + m_dim.N0 * i1;
     470             :   }
     471             : 
     472             :   // rank 3
     473             :   template <typename I0, typename I1, typename I2>
     474             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     475             :                                                         I1 const& i1,
     476             :                                                         I2 const& i2) const {
     477             :     return i0 + m_dim.N0 * (i1 + m_dim.N1 * i2);
     478             :   }
     479             : 
     480             :   // rank 4
     481             :   template <typename I0, typename I1, typename I2, typename I3>
     482             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     483             :                                                         I1 const& i1,
     484             :                                                         I2 const& i2,
     485             :                                                         I3 const& i3) const {
     486             :     return i0 + m_dim.N0 * (i1 + m_dim.N1 * (i2 + m_dim.N2 * i3));
     487             :   }
     488             : 
     489             :   // rank 5
     490             :   template <typename I0, typename I1, typename I2, typename I3, typename I4>
     491             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     492             :                                                         I1 const& i1,
     493             :                                                         I2 const& i2,
     494             :                                                         I3 const& i3,
     495             :                                                         I4 const& i4) const {
     496             :     return i0 +
     497             :            m_dim.N0 * (i1 + m_dim.N1 * (i2 + m_dim.N2 * (i3 + m_dim.N3 * i4)));
     498             :   }
     499             : 
     500             :   // rank 6
     501             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
     502             :             typename I5>
     503             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
     504             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
     505             :       I5 const& i5) const {
     506             :     return i0 +
     507             :            m_dim.N0 *
     508             :                (i1 +
     509             :                 m_dim.N1 *
     510             :                     (i2 + m_dim.N2 * (i3 + m_dim.N3 * (i4 + m_dim.N4 * i5))));
     511             :   }
     512             : 
     513             :   // rank 7
     514             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
     515             :             typename I5, typename I6>
     516             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
     517             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
     518             :       I5 const& i5, I6 const& i6) const {
     519             :     return i0 +
     520             :            m_dim.N0 *
     521             :                (i1 + m_dim.N1 *
     522             :                          (i2 + m_dim.N2 *
     523             :                                    (i3 + m_dim.N3 *
     524             :                                              (i4 + m_dim.N4 *
     525             :                                                        (i5 + m_dim.N5 * i6)))));
     526             :   }
     527             : 
     528             :   // rank 8
     529             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
     530             :             typename I5, typename I6, typename I7>
     531             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
     532             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
     533             :       I5 const& i5, I6 const& i6, I7 const& i7) const {
     534             :     return i0 +
     535             :            m_dim.N0 *
     536             :                (i1 +
     537             :                 m_dim.N1 *
     538             :                     (i2 + m_dim.N2 *
     539             :                               (i3 + m_dim.N3 *
     540             :                                         (i4 + m_dim.N4 *
     541             :                                                   (i5 + m_dim.N5 *
     542             :                                                             (i6 + m_dim.N6 *
     543             :                                                                       i7))))));
     544             :   }
     545             : 
     546             :   //----------------------------------------
     547             : 
     548             :   KOKKOS_INLINE_FUNCTION
     549             :   constexpr array_layout layout() const {
     550             :     constexpr auto r = dimension_type::rank;
     551             :     return array_layout((r > 0 ? m_dim.N0 : KOKKOS_INVALID_INDEX),
     552             :                         (r > 1 ? m_dim.N1 : KOKKOS_INVALID_INDEX),
     553             :                         (r > 2 ? m_dim.N2 : KOKKOS_INVALID_INDEX),
     554             :                         (r > 3 ? m_dim.N3 : KOKKOS_INVALID_INDEX),
     555             :                         (r > 4 ? m_dim.N4 : KOKKOS_INVALID_INDEX),
     556             :                         (r > 5 ? m_dim.N5 : KOKKOS_INVALID_INDEX),
     557             :                         (r > 6 ? m_dim.N6 : KOKKOS_INVALID_INDEX),
     558             :                         (r > 7 ? m_dim.N7 : KOKKOS_INVALID_INDEX));
     559             :   }
     560             : 
     561             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
     562             :     return m_dim.N0;
     563             :   }
     564             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const {
     565             :     return m_dim.N1;
     566             :   }
     567             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const {
     568             :     return m_dim.N2;
     569             :   }
     570             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const {
     571             :     return m_dim.N3;
     572             :   }
     573             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const {
     574             :     return m_dim.N4;
     575             :   }
     576             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const {
     577             :     return m_dim.N5;
     578             :   }
     579             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const {
     580             :     return m_dim.N6;
     581             :   }
     582             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const {
     583             :     return m_dim.N7;
     584             :   }
     585             : 
     586             :   /* Cardinality of the domain index space */
     587             :   KOKKOS_INLINE_FUNCTION
     588             :   constexpr size_type size() const {
     589             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
     590             :            m_dim.N5 * m_dim.N6 * m_dim.N7;
     591             :   }
     592             : 
     593             :   /* Span of the range space */
     594             :   KOKKOS_INLINE_FUNCTION
     595             :   constexpr size_type span() const {
     596             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
     597             :            m_dim.N5 * m_dim.N6 * m_dim.N7;
     598             :   }
     599             : 
     600             :   KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
     601             :     return true;
     602             :   }
     603             : 
     604             :   /* Strides of dimensions */
     605             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const { return 1; }
     606             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const {
     607             :     return m_dim.N0;
     608             :   }
     609             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const {
     610             :     return size_type(m_dim.N0) * m_dim.N1;
     611             :   }
     612             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const {
     613             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2;
     614             :   }
     615             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const {
     616             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3;
     617             :   }
     618             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const {
     619             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4;
     620             :   }
     621             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const {
     622             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
     623             :            m_dim.N5;
     624             :   }
     625             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const {
     626             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
     627             :            m_dim.N5 * m_dim.N6;
     628             :   }
     629             : 
     630             :   // Fill the target unbounded array s with the stride.
     631             :   // This method differs from stride() in that it does not write the total
     632             :   // length to the last index of the array. Preconditions: s must be an array of
     633             :   // dimension_type::rank elements
     634             :   // FIXME: The version of clang-format in CI fails from maybe_unused
     635             :   // clang-format off
     636             :   template <typename iType>
     637             :   KOKKOS_INLINE_FUNCTION iType
     638             :   stride_fill([[maybe_unused]] iType* const s) const {
     639             :     iType n = 1;
     640             :     if constexpr (0 < dimension_type::rank) {
     641             :       s[0] = n;
     642             :       n *= m_dim.N0;
     643             :     }
     644             :     if constexpr (1 < dimension_type::rank) {
     645             :       s[1] = n;
     646             :       n *= m_dim.N1;
     647             :     }
     648             :     if constexpr (2 < dimension_type::rank) {
     649             :       s[2] = n;
     650             :       n *= m_dim.N2;
     651             :     }
     652             :     if constexpr (3 < dimension_type::rank) {
     653             :       s[3] = n;
     654             :       n *= m_dim.N3;
     655             :     }
     656             :     if constexpr (4 < dimension_type::rank) {
     657             :       s[4] = n;
     658             :       n *= m_dim.N4;
     659             :     }
     660             :     if constexpr (5 < dimension_type::rank) {
     661             :       s[5] = n;
     662             :       n *= m_dim.N5;
     663             :     }
     664             :     if constexpr (6 < dimension_type::rank) {
     665             :       s[6] = n;
     666             :       n *= m_dim.N6;
     667             :     }
     668             :     if constexpr (7 < dimension_type::rank) {
     669             :       s[7] = n;
     670             :       n *= m_dim.N7;
     671             :     }
     672             :     return n;
     673             :   }
     674             :   // clang-format on
     675             : 
     676             :   // Fill the target unbounded array s with the stride and the total spanned
     677             :   // size. This method differs from stride_fill() in that it writes the total
     678             :   // spanned size to the last index of the array. Preconditions: s must be an
     679             :   // array of dimension_type::rank + 1 elements Stride with [ rank ] value is
     680             :   // the total length
     681             :   template <typename iType>
     682             :   KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
     683             :     s[dimension_type::rank] = stride_fill(s);
     684             :   }
     685             : 
     686             :   //----------------------------------------
     687             : 
     688             :   // MSVC (16.5.5) + CUDA (10.2) did not generate the defaulted functions
     689             :   // correct and errors out during compilation. Same for the other places where
     690             :   // I changed this.
     691             : #ifdef KOKKOS_IMPL_WINDOWS_CUDA
     692             :   KOKKOS_FUNCTION ViewOffset() : m_dim(dimension_type()) {}
     693             :   KOKKOS_FUNCTION ViewOffset(const ViewOffset& src) { m_dim = src.m_dim; }
     694             :   KOKKOS_FUNCTION ViewOffset& operator=(const ViewOffset& src) {
     695             :     m_dim = src.m_dim;
     696             :     return *this;
     697             :   }
     698             : #else
     699             :   ViewOffset()                             = default;
     700             :   ViewOffset(const ViewOffset&)            = default;
     701             :   ViewOffset& operator=(const ViewOffset&) = default;
     702             : #endif
     703             : 
     704             :   template <unsigned TrivialScalarSize>
     705             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
     706             :       std::integral_constant<unsigned, TrivialScalarSize> const&,
     707             :       Kokkos::LayoutLeft const& arg_layout)
     708             :       : m_dim(arg_layout.dimension[0], 0, 0, 0, 0, 0, 0, 0) {}
     709             : 
     710             :   template <class DimRHS>
     711             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
     712             :       const ViewOffset<DimRHS, Kokkos::LayoutLeft, void>& rhs)
     713             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
     714             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7) {
     715             :     static_assert(int(DimRHS::rank) == int(dimension_type::rank),
     716             :                   "ViewOffset assignment requires equal rank");
     717             :     // Also requires equal static dimensions ...
     718             :   }
     719             : 
     720             :   template <class DimRHS>
     721             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
     722             :       const ViewOffset<DimRHS, Kokkos::LayoutRight, void>& rhs)
     723             :       : m_dim(rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0) {
     724             :     static_assert(((DimRHS::rank == 0 && dimension_type::rank == 0) ||
     725             :                    (DimRHS::rank == 1 && dimension_type::rank == 1)),
     726             :                   "ViewOffset LayoutLeft and LayoutRight are only compatible "
     727             :                   "when rank <= 1");
     728             :   }
     729             : 
     730             :   template <class DimRHS>
     731             :   KOKKOS_INLINE_FUNCTION ViewOffset(
     732             :       const ViewOffset<DimRHS, Kokkos::LayoutStride, void>& rhs)
     733             :       : m_dim(rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0) {
     734             :     if (rhs.m_stride.S0 != 1) {
     735             :       Kokkos::abort(
     736             :           "Kokkos::Impl::ViewOffset assignment of LayoutLeft from LayoutStride "
     737             :           " requires stride == 1");
     738             :     }
     739             :   }
     740             : 
     741             :   //----------------------------------------
     742             :   // Subview construction
     743             : 
     744             :   template <class DimRHS>
     745             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
     746             :       const ViewOffset<DimRHS, Kokkos::LayoutLeft, void>&,
     747             :       const SubviewExtents<DimRHS::rank, dimension_type::rank>& sub)
     748             :       : m_dim(sub.range_extent(0), 0, 0, 0, 0, 0, 0, 0) {
     749             :     static_assert((0 == dimension_type::rank_dynamic) ||
     750             :                       (1 == dimension_type::rank &&
     751             :                        1 == dimension_type::rank_dynamic && 1 <= DimRHS::rank),
     752             :                   "ViewOffset subview construction requires compatible rank");
     753             :   }
     754             : };
     755             : 
     756             : //----------------------------------------------------------------------------
     757             : // LayoutLeft AND ( 1 < rank AND 0 < rank_dynamic ) : has padding / striding
     758             : template <class Dimension>
     759             : struct ViewOffset<
     760             :     Dimension, Kokkos::LayoutLeft,
     761             :     std::enable_if_t<(1 < Dimension::rank && 0 < Dimension::rank_dynamic)>> {
     762             :   using is_mapping_plugin = std::true_type;
     763             :   using is_regular        = std::true_type;
     764             : 
     765             :   using size_type      = size_t;
     766             :   using dimension_type = Dimension;
     767             :   using array_layout   = Kokkos::LayoutLeft;
     768             : 
     769             :   dimension_type m_dim;
     770             :   size_type m_stride;
     771             : 
     772             :   //----------------------------------------
     773             : 
     774             :   // rank 1
     775             :   template <typename I0>
     776             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0) const {
     777             :     return i0;
     778             :   }
     779             : 
     780             :   // rank 2
     781             :   template <typename I0, typename I1>
     782             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     783             :                                                         I1 const& i1) const {
     784             :     return i0 + m_stride * i1;
     785             :   }
     786             : 
     787             :   // rank 3
     788             :   template <typename I0, typename I1, typename I2>
     789             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     790             :                                                         I1 const& i1,
     791             :                                                         I2 const& i2) const {
     792             :     return i0 + m_stride * (i1 + m_dim.N1 * i2);
     793             :   }
     794             : 
     795             :   // rank 4
     796             :   template <typename I0, typename I1, typename I2, typename I3>
     797             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     798             :                                                         I1 const& i1,
     799             :                                                         I2 const& i2,
     800             :                                                         I3 const& i3) const {
     801             :     return i0 + m_stride * (i1 + m_dim.N1 * (i2 + m_dim.N2 * i3));
     802             :   }
     803             : 
     804             :   // rank 5
     805             :   template <typename I0, typename I1, typename I2, typename I3, typename I4>
     806             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
     807             :                                                         I1 const& i1,
     808             :                                                         I2 const& i2,
     809             :                                                         I3 const& i3,
     810             :                                                         I4 const& i4) const {
     811             :     return i0 +
     812             :            m_stride * (i1 + m_dim.N1 * (i2 + m_dim.N2 * (i3 + m_dim.N3 * i4)));
     813             :   }
     814             : 
     815             :   // rank 6
     816             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
     817             :             typename I5>
     818             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
     819             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
     820             :       I5 const& i5) const {
     821             :     return i0 +
     822             :            m_stride *
     823             :                (i1 +
     824             :                 m_dim.N1 *
     825             :                     (i2 + m_dim.N2 * (i3 + m_dim.N3 * (i4 + m_dim.N4 * i5))));
     826             :   }
     827             : 
     828             :   // rank 7
     829             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
     830             :             typename I5, typename I6>
     831             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
     832             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
     833             :       I5 const& i5, I6 const& i6) const {
     834             :     return i0 +
     835             :            m_stride *
     836             :                (i1 + m_dim.N1 *
     837             :                          (i2 + m_dim.N2 *
     838             :                                    (i3 + m_dim.N3 *
     839             :                                              (i4 + m_dim.N4 *
     840             :                                                        (i5 + m_dim.N5 * i6)))));
     841             :   }
     842             : 
     843             :   // rank 8
     844             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
     845             :             typename I5, typename I6, typename I7>
     846             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
     847             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
     848             :       I5 const& i5, I6 const& i6, I7 const& i7) const {
     849             :     return i0 +
     850             :            m_stride *
     851             :                (i1 +
     852             :                 m_dim.N1 *
     853             :                     (i2 + m_dim.N2 *
     854             :                               (i3 + m_dim.N3 *
     855             :                                         (i4 + m_dim.N4 *
     856             :                                                   (i5 + m_dim.N5 *
     857             :                                                             (i6 + m_dim.N6 *
     858             :                                                                       i7))))));
     859             :   }
     860             : 
     861             :   //----------------------------------------
     862             : 
     863             :   KOKKOS_INLINE_FUNCTION
     864             :   constexpr array_layout layout() const {
     865             :     constexpr auto r = dimension_type::rank;
     866             :     array_layout l((r > 0 ? m_dim.N0 : KOKKOS_INVALID_INDEX),
     867             :                    (r > 1 ? m_dim.N1 : KOKKOS_INVALID_INDEX),
     868             :                    (r > 2 ? m_dim.N2 : KOKKOS_INVALID_INDEX),
     869             :                    (r > 3 ? m_dim.N3 : KOKKOS_INVALID_INDEX),
     870             :                    (r > 4 ? m_dim.N4 : KOKKOS_INVALID_INDEX),
     871             :                    (r > 5 ? m_dim.N5 : KOKKOS_INVALID_INDEX),
     872             :                    (r > 6 ? m_dim.N6 : KOKKOS_INVALID_INDEX),
     873             :                    (r > 7 ? m_dim.N7 : KOKKOS_INVALID_INDEX));
     874             :     // Without span_is_contiguous Sacado hidden dimensions get messed up
     875             :     l.stride = span_is_contiguous() ? KOKKOS_IMPL_CTOR_DEFAULT_ARG : m_stride;
     876             :     return l;
     877             :   }
     878             : 
     879             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
     880             :     return m_dim.N0;
     881             :   }
     882             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const {
     883             :     return m_dim.N1;
     884             :   }
     885             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const {
     886             :     return m_dim.N2;
     887             :   }
     888             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const {
     889             :     return m_dim.N3;
     890             :   }
     891             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const {
     892             :     return m_dim.N4;
     893             :   }
     894             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const {
     895             :     return m_dim.N5;
     896             :   }
     897             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const {
     898             :     return m_dim.N6;
     899             :   }
     900             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const {
     901             :     return m_dim.N7;
     902             :   }
     903             : 
     904             :   /* Cardinality of the domain index space */
     905             :   KOKKOS_INLINE_FUNCTION
     906             :   constexpr size_type size() const {
     907             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
     908             :            m_dim.N5 * m_dim.N6 * m_dim.N7;
     909             :   }
     910             : 
     911             :   /* Span of the range space */
     912             :   KOKKOS_INLINE_FUNCTION
     913             :   constexpr size_type span() const {
     914             :     return (m_dim.N0 > size_type(0) ? m_stride : size_type(0)) * m_dim.N1 *
     915             :            m_dim.N2 * m_dim.N3 * m_dim.N4 * m_dim.N5 * m_dim.N6 * m_dim.N7;
     916             :   }
     917             : 
     918             :   KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
     919             :     return m_stride == m_dim.N0;
     920             :   }
     921             : 
     922             :   /* Strides of dimensions */
     923             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const { return 1; }
     924             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const {
     925             :     return m_stride;
     926             :   }
     927             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const {
     928             :     return m_stride * m_dim.N1;
     929             :   }
     930             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const {
     931             :     return m_stride * m_dim.N1 * m_dim.N2;
     932             :   }
     933             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const {
     934             :     return m_stride * m_dim.N1 * m_dim.N2 * m_dim.N3;
     935             :   }
     936             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const {
     937             :     return m_stride * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4;
     938             :   }
     939             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const {
     940             :     return m_stride * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 * m_dim.N5;
     941             :   }
     942             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const {
     943             :     return m_stride * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 * m_dim.N5 *
     944             :            m_dim.N6;
     945             :   }
     946             : 
     947             :   // Fill the target unbounded array s with the stride.
     948             :   // This method differs from stride() in that it does not write the total
     949             :   // length to the last index of the array. Preconditions: s must be an array of
     950             :   // dimension_type::rank elements
     951             :   // The version of clang-format in CI fails from maybe_unused
     952             :   // clang-format off
     953             :   template <typename iType>
     954             :   KOKKOS_INLINE_FUNCTION iType
     955             :   stride_fill([[maybe_unused]] iType* const s) const {
     956             :     iType n = 1;
     957             :     if constexpr (0 < dimension_type::rank) {
     958             :       s[0] = n;
     959             :       n *= m_stride;
     960             :     }
     961             :     if constexpr (1 < dimension_type::rank) {
     962             :       s[1] = n;
     963             :       n *= m_dim.N1;
     964             :     }
     965             :     if constexpr (2 < dimension_type::rank) {
     966             :       s[2] = n;
     967             :       n *= m_dim.N2;
     968             :     }
     969             :     if constexpr (3 < dimension_type::rank) {
     970             :       s[3] = n;
     971             :       n *= m_dim.N3;
     972             :     }
     973             :     if constexpr (4 < dimension_type::rank) {
     974             :       s[4] = n;
     975             :       n *= m_dim.N4;
     976             :     }
     977             :     if constexpr (5 < dimension_type::rank) {
     978             :       s[5] = n;
     979             :       n *= m_dim.N5;
     980             :     }
     981             :     if constexpr (6 < dimension_type::rank) {
     982             :       s[6] = n;
     983             :       n *= m_dim.N6;
     984             :     }
     985             :     if constexpr (7 < dimension_type::rank) {
     986             :       s[7] = n;
     987             :       n *= m_dim.N7;
     988             :     }
     989             :     return n;
     990             :   }
     991             :   // clang-format on
     992             : 
     993             :   // Fill the target unbounded array s with the stride and the total spanned
     994             :   // size. This method differs from stride_fill() in that it writes the total
     995             :   // spanned size to the last index of the array. Preconditions: s must be an
     996             :   // array of dimension_type::rank + 1 elements
     997             :   template <typename iType>
     998             :   KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
     999             :     s[dimension_type::rank] = stride_fill(s);
    1000             :   }
    1001             : 
    1002             :   //----------------------------------------
    1003             : 
    1004             :  private:
    1005             :   template <unsigned TrivialScalarSize>
    1006             :   struct Padding {
    1007             :     enum {
    1008             :       div = TrivialScalarSize == 0
    1009             :                 ? 0
    1010             :                 : Kokkos::Impl::MEMORY_ALIGNMENT /
    1011             :                       (TrivialScalarSize ? TrivialScalarSize : 1)
    1012             :     };
    1013             :     enum {
    1014             :       mod = TrivialScalarSize == 0
    1015             :                 ? 0
    1016             :                 : Kokkos::Impl::MEMORY_ALIGNMENT %
    1017             :                       (TrivialScalarSize ? TrivialScalarSize : 1)
    1018             :     };
    1019             : 
    1020             :     // If memory alignment is a multiple of the trivial scalar size then attempt
    1021             :     // to align.
    1022             :     enum { align = 0 != TrivialScalarSize && 0 == mod ? div : 0 };
    1023             :     enum {
    1024             :       div_ok = (div != 0) ? div : 1
    1025             :     };  // To valid modulo zero in constexpr
    1026             : 
    1027             :     KOKKOS_INLINE_FUNCTION
    1028             :     static constexpr size_t stride(size_t const N) {
    1029             :       return ((align != 0) &&
    1030             :               ((static_cast<size_t>(Kokkos::Impl::MEMORY_ALIGNMENT_THRESHOLD) *
    1031             :                 align) < N) &&
    1032             :               ((N % div_ok) != 0))
    1033             :                  ? N + align - (N % div_ok)
    1034             :                  : N;
    1035             :     }
    1036             :   };
    1037             : 
    1038             :  public:
    1039             :   // MSVC (16.5.5) + CUDA (10.2) did not generate the defaulted functions
    1040             :   // correct and errors out during compilation. Same for the other places where
    1041             :   // I changed this.
    1042             : #ifdef KOKKOS_IMPL_WINDOWS_CUDA
    1043             :   KOKKOS_FUNCTION ViewOffset() : m_dim(dimension_type()), m_stride(0) {}
    1044             :   KOKKOS_FUNCTION ViewOffset(const ViewOffset& src) {
    1045             :     m_dim    = src.m_dim;
    1046             :     m_stride = src.m_stride;
    1047             :   }
    1048             :   KOKKOS_FUNCTION ViewOffset& operator=(const ViewOffset& src) {
    1049             :     m_dim    = src.m_dim;
    1050             :     m_stride = src.m_stride;
    1051             :     return *this;
    1052             :   }
    1053             : #else
    1054             : 
    1055             :   ViewOffset()                             = default;
    1056             :   ViewOffset(const ViewOffset&)            = default;
    1057             :   ViewOffset& operator=(const ViewOffset&) = default;
    1058             : #endif
    1059             : 
    1060             :   /* Enable padding for trivial scalar types with non-zero trivial scalar size
    1061             :    */
    1062             :   template <unsigned TrivialScalarSize>
    1063             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1064             :       std::integral_constant<unsigned, TrivialScalarSize> const&,
    1065             :       Kokkos::LayoutLeft const& arg_layout)
    1066             :       : m_dim(arg_layout.dimension[0], arg_layout.dimension[1],
    1067             :               arg_layout.dimension[2], arg_layout.dimension[3],
    1068             :               arg_layout.dimension[4], arg_layout.dimension[5],
    1069             :               arg_layout.dimension[6], arg_layout.dimension[7]),
    1070             :         m_stride(
    1071             :             arg_layout.stride != KOKKOS_IMPL_CTOR_DEFAULT_ARG
    1072             :                 ? arg_layout.stride
    1073             :                 : Padding<TrivialScalarSize>::stride(arg_layout.dimension[0])) {
    1074             :   }
    1075             : 
    1076             :   template <class DimRHS>
    1077             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1078             :       const ViewOffset<DimRHS, Kokkos::LayoutLeft, void>& rhs)
    1079             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
    1080             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7),
    1081             :         m_stride(rhs.stride_1()) {
    1082             :     static_assert(int(DimRHS::rank) == int(dimension_type::rank),
    1083             :                   "ViewOffset assignment requires equal rank");
    1084             :     // Also requires equal static dimensions ...
    1085             :   }
    1086             : 
    1087             :   template <class DimRHS>
    1088             :   KOKKOS_INLINE_FUNCTION ViewOffset(
    1089             :       const ViewOffset<DimRHS, Kokkos::LayoutStride, void>& rhs)
    1090             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
    1091             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7),
    1092             :         m_stride(rhs.stride_1()) {
    1093             :     if (rhs.m_stride.S0 != 1) {
    1094             :       Kokkos::abort(
    1095             :           "Kokkos::Impl::ViewOffset assignment of LayoutLeft from LayoutStride "
    1096             :           "requires stride == 1");
    1097             :     }
    1098             :   }
    1099             : 
    1100             :   //----------------------------------------
    1101             :   // Subview construction
    1102             :   // This subview must be 2 == rank and 2 == rank_dynamic
    1103             :   // due to only having stride #0.
    1104             :   // The source dimension #0 must be non-zero for stride-one leading dimension.
    1105             :   // At most subsequent dimension can be non-zero.
    1106             : 
    1107             :   template <class DimRHS>
    1108             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1109             :       const ViewOffset<DimRHS, Kokkos::LayoutLeft, void>& rhs,
    1110             :       const SubviewExtents<DimRHS::rank, dimension_type::rank>& sub)
    1111             :       : m_dim(sub.range_extent(0), sub.range_extent(1), sub.range_extent(2),
    1112             :               sub.range_extent(3), sub.range_extent(4), sub.range_extent(5),
    1113             :               sub.range_extent(6), sub.range_extent(7)),
    1114             :         m_stride(
    1115             :             (1 == sub.range_index(1)
    1116             :                  ? rhs.stride_1()
    1117             :                  : (2 == sub.range_index(1)
    1118             :                         ? rhs.stride_2()
    1119             :                         : (3 == sub.range_index(1)
    1120             :                                ? rhs.stride_3()
    1121             :                                : (4 == sub.range_index(1)
    1122             :                                       ? rhs.stride_4()
    1123             :                                       : (5 == sub.range_index(1)
    1124             :                                              ? rhs.stride_5()
    1125             :                                              : (6 == sub.range_index(1)
    1126             :                                                     ? rhs.stride_6()
    1127             :                                                     : (7 == sub.range_index(1)
    1128             :                                                            ? rhs.stride_7()
    1129             :                                                            : 0)))))))) {
    1130             :     // static_assert( ( 2 == dimension_type::rank ) &&
    1131             :     //               ( 2 == dimension_type::rank_dynamic ) &&
    1132             :     //               ( 2 <= DimRHS::rank )
    1133             :     //             , "ViewOffset subview construction requires compatible rank"
    1134             :     //             );
    1135             :   }
    1136             : };
    1137             : 
    1138             : //----------------------------------------------------------------------------
    1139             : // LayoutRight AND ( 1 >= rank OR 0 == rank_dynamic ) : no padding / striding
    1140             : template <class Dimension>
    1141             : struct ViewOffset<
    1142             :     Dimension, Kokkos::LayoutRight,
    1143             :     std::enable_if_t<(1 >= Dimension::rank || 0 == Dimension::rank_dynamic)>> {
    1144             :   using is_mapping_plugin = std::true_type;
    1145             :   using is_regular        = std::true_type;
    1146             : 
    1147             :   using size_type      = size_t;
    1148             :   using dimension_type = Dimension;
    1149             :   using array_layout   = Kokkos::LayoutRight;
    1150             : 
    1151             :   dimension_type m_dim;
    1152             : 
    1153             :   //----------------------------------------
    1154             : 
    1155             :   // rank 1
    1156             :   template <typename I0>
    1157             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0) const {
    1158             :     return i0;
    1159             :   }
    1160             : 
    1161             :   // rank 2
    1162             :   template <typename I0, typename I1>
    1163             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1164             :                                                         I1 const& i1) const {
    1165             :     return i1 + m_dim.N1 * i0;
    1166             :   }
    1167             : 
    1168             :   // rank 3
    1169             :   template <typename I0, typename I1, typename I2>
    1170             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1171             :                                                         I1 const& i1,
    1172             :                                                         I2 const& i2) const {
    1173             :     return i2 + m_dim.N2 * (i1 + m_dim.N1 * (i0));
    1174             :   }
    1175             : 
    1176             :   // rank 4
    1177             :   template <typename I0, typename I1, typename I2, typename I3>
    1178             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1179             :                                                         I1 const& i1,
    1180             :                                                         I2 const& i2,
    1181             :                                                         I3 const& i3) const {
    1182             :     return i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1 + m_dim.N1 * (i0)));
    1183             :   }
    1184             : 
    1185             :   // rank 5
    1186             :   template <typename I0, typename I1, typename I2, typename I3, typename I4>
    1187             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1188             :                                                         I1 const& i1,
    1189             :                                                         I2 const& i2,
    1190             :                                                         I3 const& i3,
    1191             :                                                         I4 const& i4) const {
    1192             :     return i4 + m_dim.N4 *
    1193             :                     (i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1 + m_dim.N1 * (i0))));
    1194             :   }
    1195             : 
    1196             :   // rank 6
    1197             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    1198             :             typename I5>
    1199             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    1200             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    1201             :       I5 const& i5) const {
    1202             :     return i5 +
    1203             :            m_dim.N5 *
    1204             :                (i4 +
    1205             :                 m_dim.N4 *
    1206             :                     (i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1 + m_dim.N1 * (i0)))));
    1207             :   }
    1208             : 
    1209             :   // rank 7
    1210             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    1211             :             typename I5, typename I6>
    1212             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    1213             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    1214             :       I5 const& i5, I6 const& i6) const {
    1215             :     return i6 +
    1216             :            m_dim.N6 *
    1217             :                (i5 +
    1218             :                 m_dim.N5 *
    1219             :                     (i4 +
    1220             :                      m_dim.N4 *
    1221             :                          (i3 + m_dim.N3 *
    1222             :                                    (i2 + m_dim.N2 * (i1 + m_dim.N1 * (i0))))));
    1223             :   }
    1224             : 
    1225             :   // rank 8
    1226             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    1227             :             typename I5, typename I6, typename I7>
    1228             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    1229             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    1230             :       I5 const& i5, I6 const& i6, I7 const& i7) const {
    1231             :     return i7 +
    1232             :            m_dim.N7 *
    1233             :                (i6 +
    1234             :                 m_dim.N6 *
    1235             :                     (i5 +
    1236             :                      m_dim.N5 *
    1237             :                          (i4 +
    1238             :                           m_dim.N4 *
    1239             :                               (i3 +
    1240             :                                m_dim.N3 *
    1241             :                                    (i2 + m_dim.N2 * (i1 + m_dim.N1 * (i0)))))));
    1242             :   }
    1243             : 
    1244             :   //----------------------------------------
    1245             : 
    1246             :   KOKKOS_INLINE_FUNCTION
    1247             :   constexpr array_layout layout() const {
    1248             :     constexpr auto r = dimension_type::rank;
    1249             :     return array_layout((r > 0 ? m_dim.N0 : KOKKOS_INVALID_INDEX),
    1250             :                         (r > 1 ? m_dim.N1 : KOKKOS_INVALID_INDEX),
    1251             :                         (r > 2 ? m_dim.N2 : KOKKOS_INVALID_INDEX),
    1252             :                         (r > 3 ? m_dim.N3 : KOKKOS_INVALID_INDEX),
    1253             :                         (r > 4 ? m_dim.N4 : KOKKOS_INVALID_INDEX),
    1254             :                         (r > 5 ? m_dim.N5 : KOKKOS_INVALID_INDEX),
    1255             :                         (r > 6 ? m_dim.N6 : KOKKOS_INVALID_INDEX),
    1256             :                         (r > 7 ? m_dim.N7 : KOKKOS_INVALID_INDEX));
    1257             :   }
    1258             : 
    1259     1378872 :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
    1260     1378872 :     return m_dim.N0;
    1261             :   }
    1262             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const {
    1263             :     return m_dim.N1;
    1264             :   }
    1265             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const {
    1266             :     return m_dim.N2;
    1267             :   }
    1268             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const {
    1269             :     return m_dim.N3;
    1270             :   }
    1271             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const {
    1272             :     return m_dim.N4;
    1273             :   }
    1274             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const {
    1275             :     return m_dim.N5;
    1276             :   }
    1277             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const {
    1278             :     return m_dim.N6;
    1279             :   }
    1280             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const {
    1281             :     return m_dim.N7;
    1282             :   }
    1283             : 
    1284             :   /* Cardinality of the domain index space */
    1285             :   KOKKOS_INLINE_FUNCTION
    1286             :   constexpr size_type size() const {
    1287             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
    1288             :            m_dim.N5 * m_dim.N6 * m_dim.N7;
    1289             :   }
    1290             : 
    1291             :   /* Span of the range space */
    1292             :   KOKKOS_INLINE_FUNCTION
    1293             :   constexpr size_type span() const {
    1294             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
    1295             :            m_dim.N5 * m_dim.N6 * m_dim.N7;
    1296             :   }
    1297             : 
    1298             :   KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
    1299             :     return true;
    1300             :   }
    1301             : 
    1302             :   /* Strides of dimensions */
    1303             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const { return 1; }
    1304             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const {
    1305             :     return m_dim.N7;
    1306             :   }
    1307             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const {
    1308             :     return m_dim.N7 * m_dim.N6;
    1309             :   }
    1310             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const {
    1311             :     return m_dim.N7 * m_dim.N6 * m_dim.N5;
    1312             :   }
    1313             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const {
    1314             :     return m_dim.N7 * m_dim.N6 * m_dim.N5 * m_dim.N4;
    1315             :   }
    1316             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const {
    1317             :     return m_dim.N7 * m_dim.N6 * m_dim.N5 * m_dim.N4 * m_dim.N3;
    1318             :   }
    1319             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const {
    1320             :     return m_dim.N7 * m_dim.N6 * m_dim.N5 * m_dim.N4 * m_dim.N3 * m_dim.N2;
    1321             :   }
    1322             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const {
    1323             :     return m_dim.N7 * m_dim.N6 * m_dim.N5 * m_dim.N4 * m_dim.N3 * m_dim.N2 *
    1324             :            m_dim.N1;
    1325             :   }
    1326             : 
    1327             :   // Fill the target unbounded array s with the stride.
    1328             :   // This method differs from stride() in that it does not write the total
    1329             :   // length to the last index of the array. Preconditions: s must be an array of
    1330             :   // dimension_type::rank elements
    1331             :   // The version of clang-format in CI fails from maybe_unused
    1332             :   // clang-format off
    1333             :   template <typename iType>
    1334             :   KOKKOS_INLINE_FUNCTION iType
    1335             :   stride_fill([[maybe_unused]] iType* const s) const {
    1336             :     size_type n = 1;
    1337             :     if constexpr (7 < dimension_type::rank) {
    1338             :       s[7] = n;
    1339             :       n *= m_dim.N7;
    1340             :     }
    1341             :     if constexpr (6 < dimension_type::rank) {
    1342             :       s[6] = n;
    1343             :       n *= m_dim.N6;
    1344             :     }
    1345             :     if constexpr (5 < dimension_type::rank) {
    1346             :       s[5] = n;
    1347             :       n *= m_dim.N5;
    1348             :     }
    1349             :     if constexpr (4 < dimension_type::rank) {
    1350             :       s[4] = n;
    1351             :       n *= m_dim.N4;
    1352             :     }
    1353             :     if constexpr (3 < dimension_type::rank) {
    1354             :       s[3] = n;
    1355             :       n *= m_dim.N3;
    1356             :     }
    1357             :     if constexpr (2 < dimension_type::rank) {
    1358             :       s[2] = n;
    1359             :       n *= m_dim.N2;
    1360             :     }
    1361             :     if constexpr (1 < dimension_type::rank) {
    1362             :       s[1] = n;
    1363             :       n *= m_dim.N1;
    1364             :     }
    1365             :     if constexpr (0 < dimension_type::rank) {
    1366             :       s[0] = n;
    1367             :     }
    1368             :     return n * m_dim.N0;
    1369             :   }
    1370             :   // clang-format on
    1371             : 
    1372             :   // Fill the target unbounded array s with the stride and the total spanned
    1373             :   // size. This method differs from stride_fill() in that it writes the total
    1374             :   // spanned size to the last index of the array. Preconditions: s must be an
    1375             :   // array of dimension_type::rank + 1 elements
    1376             :   template <typename iType>
    1377             :   KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
    1378             :     s[dimension_type::rank] = stride_fill(s);
    1379             :   }
    1380             : 
    1381             :   //----------------------------------------
    1382             :   // MSVC (16.5.5) + CUDA (10.2) did not generate the defaulted functions
    1383             :   // correct and errors out during compilation. Same for the other places where
    1384             :   // I changed this.
    1385             : 
    1386             : #ifdef KOKKOS_IMPL_WINDOWS_CUDA
    1387             :   KOKKOS_FUNCTION ViewOffset() : m_dim(dimension_type()) {}
    1388             :   KOKKOS_FUNCTION ViewOffset(const ViewOffset& src) { m_dim = src.m_dim; }
    1389             :   KOKKOS_FUNCTION ViewOffset& operator=(const ViewOffset& src) {
    1390             :     m_dim = src.m_dim;
    1391             :     return *this;
    1392             :   }
    1393             : #else
    1394             : 
    1395             :   ViewOffset()                             = default;
    1396             :   ViewOffset(const ViewOffset&)            = default;
    1397             :   ViewOffset& operator=(const ViewOffset&) = default;
    1398             : #endif
    1399             : 
    1400             :   template <unsigned TrivialScalarSize>
    1401             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1402             :       std::integral_constant<unsigned, TrivialScalarSize> const&,
    1403             :       Kokkos::LayoutRight const& arg_layout)
    1404             :       : m_dim(arg_layout.dimension[0], 0, 0, 0, 0, 0, 0, 0) {}
    1405             : 
    1406             :   template <class DimRHS>
    1407             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1408             :       const ViewOffset<DimRHS, Kokkos::LayoutRight, void>& rhs)
    1409             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
    1410             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7) {
    1411             :     static_assert(int(DimRHS::rank) == int(dimension_type::rank),
    1412             :                   "ViewOffset assignment requires equal rank");
    1413             :     // Also requires equal static dimensions ...
    1414             :   }
    1415             : 
    1416             :   template <class DimRHS>
    1417             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1418             :       const ViewOffset<DimRHS, Kokkos::LayoutLeft, void>& rhs)
    1419             :       : m_dim(rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0) {
    1420             :     static_assert((DimRHS::rank == 0 && dimension_type::rank == 0) ||
    1421             :                       (DimRHS::rank == 1 && dimension_type::rank == 1),
    1422             :                   "ViewOffset LayoutRight and LayoutLeft are only compatible "
    1423             :                   "when rank <= 1");
    1424             :   }
    1425             : 
    1426             :   template <class DimRHS>
    1427             :   KOKKOS_INLINE_FUNCTION ViewOffset(
    1428             :       const ViewOffset<DimRHS, Kokkos::LayoutStride, void>& rhs)
    1429             :       : m_dim(rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0) {}
    1430             : 
    1431             :   //----------------------------------------
    1432             :   // Subview construction
    1433             : 
    1434             :   template <class DimRHS>
    1435             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1436             :       const ViewOffset<DimRHS, Kokkos::LayoutRight, void>&,
    1437             :       const SubviewExtents<DimRHS::rank, dimension_type::rank>& sub)
    1438             :       : m_dim(sub.range_extent(0), 0, 0, 0, 0, 0, 0, 0) {
    1439             :     static_assert((0 == dimension_type::rank_dynamic) ||
    1440             :                       (1 == dimension_type::rank &&
    1441             :                        1 == dimension_type::rank_dynamic && 1 <= DimRHS::rank),
    1442             :                   "ViewOffset subview construction requires compatible rank");
    1443             :   }
    1444             : };
    1445             : 
    1446             : //----------------------------------------------------------------------------
    1447             : // LayoutRight AND ( 1 < rank AND 0 < rank_dynamic ) : has padding / striding
    1448             : template <class Dimension>
    1449             : struct ViewOffset<
    1450             :     Dimension, Kokkos::LayoutRight,
    1451             :     std::enable_if_t<(1 < Dimension::rank && 0 < Dimension::rank_dynamic)>> {
    1452             :   using is_mapping_plugin = std::true_type;
    1453             :   using is_regular        = std::true_type;
    1454             : 
    1455             :   using size_type      = size_t;
    1456             :   using dimension_type = Dimension;
    1457             :   using array_layout   = Kokkos::LayoutRight;
    1458             : 
    1459             :   dimension_type m_dim;
    1460             :   size_type m_stride;
    1461             : 
    1462             :   //----------------------------------------
    1463             : 
    1464             :   // rank 1
    1465             :   template <typename I0>
    1466             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0) const {
    1467             :     return i0;
    1468             :   }
    1469             : 
    1470             :   // rank 2
    1471             :   template <typename I0, typename I1>
    1472             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1473             :                                                         I1 const& i1) const {
    1474             :     return i1 + i0 * m_stride;
    1475             :   }
    1476             : 
    1477             :   // rank 3
    1478             :   template <typename I0, typename I1, typename I2>
    1479             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1480             :                                                         I1 const& i1,
    1481             :                                                         I2 const& i2) const {
    1482             :     return i2 + m_dim.N2 * (i1) + i0 * m_stride;
    1483             :   }
    1484             : 
    1485             :   // rank 4
    1486             :   template <typename I0, typename I1, typename I2, typename I3>
    1487             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1488             :                                                         I1 const& i1,
    1489             :                                                         I2 const& i2,
    1490             :                                                         I3 const& i3) const {
    1491             :     return i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1)) + i0 * m_stride;
    1492             :   }
    1493             : 
    1494             :   // rank 5
    1495             :   template <typename I0, typename I1, typename I2, typename I3, typename I4>
    1496             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    1497             :                                                         I1 const& i1,
    1498             :                                                         I2 const& i2,
    1499             :                                                         I3 const& i3,
    1500             :                                                         I4 const& i4) const {
    1501             :     return i4 + m_dim.N4 * (i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1))) +
    1502             :            i0 * m_stride;
    1503             :   }
    1504             : 
    1505             :   // rank 6
    1506             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    1507             :             typename I5>
    1508             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    1509             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    1510             :       I5 const& i5) const {
    1511             :     return i5 +
    1512             :            m_dim.N5 *
    1513             :                (i4 + m_dim.N4 * (i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1)))) +
    1514             :            i0 * m_stride;
    1515             :   }
    1516             : 
    1517             :   // rank 7
    1518             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    1519             :             typename I5, typename I6>
    1520             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    1521             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    1522             :       I5 const& i5, I6 const& i6) const {
    1523             :     return i6 +
    1524             :            m_dim.N6 *
    1525             :                (i5 + m_dim.N5 *
    1526             :                          (i4 + m_dim.N4 *
    1527             :                                    (i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1))))) +
    1528             :            i0 * m_stride;
    1529             :   }
    1530             : 
    1531             :   // rank 8
    1532             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    1533             :             typename I5, typename I6, typename I7>
    1534             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    1535             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    1536             :       I5 const& i5, I6 const& i6, I7 const& i7) const {
    1537             :     return i7 +
    1538             :            m_dim.N7 *
    1539             :                (i6 +
    1540             :                 m_dim.N6 *
    1541             :                     (i5 +
    1542             :                      m_dim.N5 *
    1543             :                          (i4 + m_dim.N4 *
    1544             :                                    (i3 + m_dim.N3 * (i2 + m_dim.N2 * (i1)))))) +
    1545             :            i0 * m_stride;
    1546             :   }
    1547             : 
    1548             :   //----------------------------------------
    1549             : 
    1550             :   KOKKOS_INLINE_FUNCTION
    1551             :   constexpr array_layout layout() const {
    1552             :     constexpr auto r = dimension_type::rank;
    1553             :     array_layout l((r > 0 ? m_dim.N0 : KOKKOS_INVALID_INDEX),
    1554             :                    (r > 1 ? m_dim.N1 : KOKKOS_INVALID_INDEX),
    1555             :                    (r > 2 ? m_dim.N2 : KOKKOS_INVALID_INDEX),
    1556             :                    (r > 3 ? m_dim.N3 : KOKKOS_INVALID_INDEX),
    1557             :                    (r > 4 ? m_dim.N4 : KOKKOS_INVALID_INDEX),
    1558             :                    (r > 5 ? m_dim.N5 : KOKKOS_INVALID_INDEX),
    1559             :                    (r > 6 ? m_dim.N6 : KOKKOS_INVALID_INDEX),
    1560             :                    (r > 7 ? m_dim.N7 : KOKKOS_INVALID_INDEX));
    1561             :     // Without span_is_contiguous Sacado hidden dimensions get messed up
    1562             :     l.stride = span_is_contiguous() ? KOKKOS_IMPL_CTOR_DEFAULT_ARG : m_stride;
    1563             :     return l;
    1564             :   }
    1565             : 
    1566             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
    1567             :     return m_dim.N0;
    1568             :   }
    1569             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const {
    1570             :     return m_dim.N1;
    1571             :   }
    1572             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const {
    1573             :     return m_dim.N2;
    1574             :   }
    1575             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const {
    1576             :     return m_dim.N3;
    1577             :   }
    1578             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const {
    1579             :     return m_dim.N4;
    1580             :   }
    1581             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const {
    1582             :     return m_dim.N5;
    1583             :   }
    1584             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const {
    1585             :     return m_dim.N6;
    1586             :   }
    1587             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const {
    1588             :     return m_dim.N7;
    1589             :   }
    1590             : 
    1591             :   /* Cardinality of the domain index space */
    1592             :   KOKKOS_INLINE_FUNCTION
    1593             :   constexpr size_type size() const {
    1594             :     return size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 *
    1595             :            m_dim.N5 * m_dim.N6 * m_dim.N7;
    1596             :   }
    1597             : 
    1598             :   /* Span of the range space */
    1599             :   KOKKOS_INLINE_FUNCTION
    1600             :   constexpr size_type span() const {
    1601             :     return size() > 0 ? size_type(m_dim.N0) * m_stride : 0;
    1602             :   }
    1603             : 
    1604             :   KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
    1605             :     return m_stride == static_cast<size_type>(m_dim.N7) * m_dim.N6 * m_dim.N5 *
    1606             :                            m_dim.N4 * m_dim.N3 * m_dim.N2 * m_dim.N1;
    1607             :   }
    1608             : 
    1609             :   /* Strides of dimensions */
    1610             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const { return 1; }
    1611             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const {
    1612             :     return m_dim.N7;
    1613             :   }
    1614             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const {
    1615             :     return static_cast<size_type>(m_dim.N7) * m_dim.N6;
    1616             :   }
    1617             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const {
    1618             :     return static_cast<size_type>(m_dim.N7) * m_dim.N6 * m_dim.N5;
    1619             :   }
    1620             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const {
    1621             :     return static_cast<size_type>(m_dim.N7) * m_dim.N6 * m_dim.N5 * m_dim.N4;
    1622             :   }
    1623             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const {
    1624             :     return static_cast<size_type>(m_dim.N7) * m_dim.N6 * m_dim.N5 * m_dim.N4 *
    1625             :            m_dim.N3;
    1626             :   }
    1627             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const {
    1628             :     return static_cast<size_type>(m_dim.N7) * m_dim.N6 * m_dim.N5 * m_dim.N4 *
    1629             :            m_dim.N3 * m_dim.N2;
    1630             :   }
    1631             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const {
    1632             :     return m_stride;
    1633             :   }
    1634             : 
    1635             :   // Fill the target unbounded array s with the stride.
    1636             :   // This method differs from stride() in that it does not write the total
    1637             :   // length to the last index of the array. Preconditions: s must be an array of
    1638             :   // dimension_type::rank elements
    1639             :   // The version of clang-format in CI fails from maybe_unused
    1640             :   // clang-format off
    1641             :   template <typename iType>
    1642             :   KOKKOS_INLINE_FUNCTION iType
    1643             :   stride_fill([[maybe_unused]] iType* const s) const {
    1644             :     size_type n = 1;
    1645             :     if constexpr (7 < dimension_type::rank) {
    1646             :       s[7] = n;
    1647             :       n *= m_dim.N7;
    1648             :     }
    1649             :     if constexpr (6 < dimension_type::rank) {
    1650             :       s[6] = n;
    1651             :       n *= m_dim.N6;
    1652             :     }
    1653             :     if constexpr (5 < dimension_type::rank) {
    1654             :       s[5] = n;
    1655             :       n *= m_dim.N5;
    1656             :     }
    1657             :     if constexpr (4 < dimension_type::rank) {
    1658             :       s[4] = n;
    1659             :       n *= m_dim.N4;
    1660             :     }
    1661             :     if constexpr (3 < dimension_type::rank) {
    1662             :       s[3] = n;
    1663             :       n *= m_dim.N3;
    1664             :     }
    1665             :     if constexpr (2 < dimension_type::rank) {
    1666             :       s[2] = n;
    1667             :       n *= m_dim.N2;
    1668             :     }
    1669             :     if constexpr (1 < dimension_type::rank) {
    1670             :       s[1] = n;
    1671             :     }
    1672             :     if constexpr (0 < dimension_type::rank) {
    1673             :       s[0] = m_stride;
    1674             :     }
    1675             :     return m_stride * m_dim.N0;
    1676             :   }
    1677             :   // clang-format on
    1678             : 
    1679             :   // Fill the target unbounded array s with the stride and the total spanned
    1680             :   // size. This method differs from stride_fill() in that it writes the total
    1681             :   // spanned size to the last index of the array. Preconditions: s must be an
    1682             :   // array of dimension_type::rank + 1 elements
    1683             :   template <typename iType>
    1684             :   KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
    1685             :     s[dimension_type::rank] = stride_fill(s);
    1686             :   }
    1687             : 
    1688             :   //----------------------------------------
    1689             : 
    1690             :  private:
    1691             :   template <unsigned TrivialScalarSize>
    1692             :   struct Padding {
    1693             :     enum {
    1694             :       div = TrivialScalarSize == 0
    1695             :                 ? 0
    1696             :                 : Kokkos::Impl::MEMORY_ALIGNMENT /
    1697             :                       (TrivialScalarSize ? TrivialScalarSize : 1)
    1698             :     };
    1699             :     enum {
    1700             :       mod = TrivialScalarSize == 0
    1701             :                 ? 0
    1702             :                 : Kokkos::Impl::MEMORY_ALIGNMENT %
    1703             :                       (TrivialScalarSize ? TrivialScalarSize : 1)
    1704             :     };
    1705             : 
    1706             :     // If memory alignment is a multiple of the trivial scalar size then attempt
    1707             :     // to align.
    1708             :     enum { align = 0 != TrivialScalarSize && 0 == mod ? div : 0 };
    1709             :     enum {
    1710             :       div_ok = (div != 0) ? div : 1
    1711             :     };  // To valid modulo zero in constexpr
    1712             : 
    1713             :     KOKKOS_INLINE_FUNCTION
    1714             :     static constexpr size_t stride(size_t const N) {
    1715             :       return ((align != 0) &&
    1716             :               ((static_cast<size_t>(Kokkos::Impl::MEMORY_ALIGNMENT_THRESHOLD) *
    1717             :                 align) < N) &&
    1718             :               ((N % div_ok) != 0))
    1719             :                  ? N + align - (N % div_ok)
    1720             :                  : N;
    1721             :     }
    1722             :   };
    1723             : 
    1724             :  public:
    1725             :   // MSVC (16.5.5) + CUDA (10.2) did not generate the defaulted functions
    1726             :   // correct and errors out during compilation. Same for the other places where
    1727             :   // I changed this.
    1728             : 
    1729             : #ifdef KOKKOS_IMPL_WINDOWS_CUDA
    1730             :   KOKKOS_FUNCTION ViewOffset() : m_dim(dimension_type()), m_stride(0) {}
    1731             :   KOKKOS_FUNCTION ViewOffset(const ViewOffset& src) {
    1732             :     m_dim    = src.m_dim;
    1733             :     m_stride = src.m_stride;
    1734             :   }
    1735             :   KOKKOS_FUNCTION ViewOffset& operator=(const ViewOffset& src) {
    1736             :     m_dim    = src.m_dim;
    1737             :     m_stride = src.m_stride;
    1738             :     return *this;
    1739             :   }
    1740             : #else
    1741             : 
    1742             :   ViewOffset()                             = default;
    1743             :   ViewOffset(const ViewOffset&)            = default;
    1744             :   ViewOffset& operator=(const ViewOffset&) = default;
    1745             : #endif
    1746             : 
    1747             :   /* Enable padding for trivial scalar types with non-zero trivial scalar size.
    1748             :    */
    1749             : 
    1750             :  private:
    1751             :   template <unsigned TrivialScalarSize>
    1752             :   KOKKOS_FUNCTION constexpr size_type compute_stride(
    1753             :       const Kokkos::LayoutRight& arg_layout) {
    1754             :     if (arg_layout.stride != KOKKOS_IMPL_CTOR_DEFAULT_ARG)
    1755             :       return arg_layout.stride;
    1756             :     size_type value = m_dim.N1;
    1757             :     if constexpr (dimension_type::rank > 2) value *= m_dim.N2;
    1758             :     if constexpr (dimension_type::rank > 3) value *= m_dim.N3;
    1759             :     if constexpr (dimension_type::rank > 4) value *= m_dim.N4;
    1760             :     if constexpr (dimension_type::rank > 5) value *= m_dim.N5;
    1761             :     if constexpr (dimension_type::rank > 6) value *= m_dim.N6;
    1762             :     if constexpr (dimension_type::rank > 7) value *= m_dim.N7;
    1763             :     return Padding<TrivialScalarSize>::stride(value);
    1764             :   }
    1765             : 
    1766             :  public:
    1767             :   template <unsigned TrivialScalarSize>
    1768             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1769             :       std::integral_constant<unsigned, TrivialScalarSize> const&,
    1770             :       Kokkos::LayoutRight const& arg_layout)
    1771             :       : m_dim(arg_layout.dimension[0], arg_layout.dimension[1],
    1772             :               arg_layout.dimension[2], arg_layout.dimension[3],
    1773             :               arg_layout.dimension[4], arg_layout.dimension[5],
    1774             :               arg_layout.dimension[6], arg_layout.dimension[7]),
    1775             :         m_stride(compute_stride<TrivialScalarSize>(arg_layout)) {}
    1776             : 
    1777             :   template <class DimRHS>
    1778             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1779             :       const ViewOffset<DimRHS, Kokkos::LayoutRight, void>& rhs)
    1780             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
    1781             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7),
    1782             :         m_stride(rhs.stride_0()) {
    1783             :     static_assert(int(DimRHS::rank) == int(dimension_type::rank),
    1784             :                   "ViewOffset assignment requires equal rank");
    1785             :     // Also requires equal static dimensions ...
    1786             :   }
    1787             : 
    1788             :   template <class DimRHS>
    1789             :   KOKKOS_INLINE_FUNCTION ViewOffset(
    1790             :       const ViewOffset<DimRHS, Kokkos::LayoutStride, void>& rhs)
    1791             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
    1792             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7),
    1793             :         m_stride(rhs.stride_0()) {
    1794             :     if (((dimension_type::rank == 2)
    1795             :              ? rhs.m_stride.S1
    1796             :              : ((dimension_type::rank == 3)
    1797             :                     ? rhs.m_stride.S2
    1798             :                     : ((dimension_type::rank == 4)
    1799             :                            ? rhs.m_stride.S3
    1800             :                            : ((dimension_type::rank == 5)
    1801             :                                   ? rhs.m_stride.S4
    1802             :                                   : ((dimension_type::rank == 6)
    1803             :                                          ? rhs.m_stride.S5
    1804             :                                          : ((dimension_type::rank == 7)
    1805             :                                                 ? rhs.m_stride.S6
    1806             :                                                 : rhs.m_stride.S7)))))) != 1) {
    1807             :       Kokkos::abort(
    1808             :           "Kokkos::Impl::ViewOffset assignment of LayoutRight from "
    1809             :           "LayoutStride requires right-most stride == 1");
    1810             :     }
    1811             :   }
    1812             : 
    1813             :   //----------------------------------------
    1814             :   // Subview construction
    1815             :   // Last dimension must be non-zero
    1816             : 
    1817             :   template <class DimRHS>
    1818             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    1819             :       const ViewOffset<DimRHS, Kokkos::LayoutRight, void>& rhs,
    1820             :       const SubviewExtents<DimRHS::rank, dimension_type::rank>& sub)
    1821             :       : m_dim(sub.range_extent(0), sub.range_extent(1), sub.range_extent(2),
    1822             :               sub.range_extent(3), sub.range_extent(4), sub.range_extent(5),
    1823             :               sub.range_extent(6), sub.range_extent(7)),
    1824             :         m_stride(
    1825             :             0 == sub.range_index(0)
    1826             :                 ? rhs.stride_0()
    1827             :                 : (1 == sub.range_index(0)
    1828             :                        ? rhs.stride_1()
    1829             :                        : (2 == sub.range_index(0)
    1830             :                               ? rhs.stride_2()
    1831             :                               : (3 == sub.range_index(0)
    1832             :                                      ? rhs.stride_3()
    1833             :                                      : (4 == sub.range_index(0)
    1834             :                                             ? rhs.stride_4()
    1835             :                                             : (5 == sub.range_index(0)
    1836             :                                                    ? rhs.stride_5()
    1837             :                                                    : (6 == sub.range_index(0)
    1838             :                                                           ? rhs.stride_6()
    1839             :                                                           : 0))))))) {
    1840             :     /*      // This subview must be 2 == rank and 2 == rank_dynamic
    1841             :           // due to only having stride #0.
    1842             :           // The source dimension #0 must be non-zero for stride-one leading
    1843             :        dimension.
    1844             :           // At most subsequent dimension can be non-zero.
    1845             : 
    1846             :           static_assert( (( 2 == dimension_type::rank ) &&
    1847             :                           ( 2 <= DimRHS::rank )) ||
    1848             :                          ()
    1849             :                        , "ViewOffset subview construction requires compatible
    1850             :        rank" );
    1851             :     */
    1852             :   }
    1853             : };
    1854             : 
    1855             : //----------------------------------------------------------------------------
    1856             : /* Strided array layout only makes sense for 0 < rank */
    1857             : /* rank = 0 included for DynRankView case */
    1858             : 
    1859             : template <unsigned Rank>
    1860             : struct ViewStride;
    1861             : 
    1862             : template <>
    1863             : struct ViewStride<0> {
    1864             :   static constexpr size_t S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0,
    1865             :                           S6 = 0, S7 = 0;
    1866             : 
    1867             :   ViewStride()                             = default;
    1868             :   ViewStride(const ViewStride&)            = default;
    1869             :   ViewStride& operator=(const ViewStride&) = default;
    1870             : 
    1871             :   KOKKOS_INLINE_FUNCTION
    1872             :   constexpr ViewStride(size_t, size_t, size_t, size_t, size_t, size_t, size_t,
    1873             :                        size_t) {}
    1874             : };
    1875             : 
    1876             : template <>
    1877             : struct ViewStride<1> {
    1878             :   size_t S0;
    1879             :   static constexpr size_t S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0,
    1880             :                           S7 = 0;
    1881             : 
    1882             :   ViewStride()                             = default;
    1883             :   ViewStride(const ViewStride&)            = default;
    1884             :   ViewStride& operator=(const ViewStride&) = default;
    1885             : 
    1886             :   KOKKOS_INLINE_FUNCTION
    1887             :   constexpr ViewStride(size_t aS0, size_t, size_t, size_t, size_t, size_t,
    1888             :                        size_t, size_t)
    1889             :       : S0(aS0) {}
    1890             : };
    1891             : 
    1892             : template <>
    1893             : struct ViewStride<2> {
    1894             :   size_t S0, S1;
    1895             :   static constexpr size_t S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0;
    1896             : 
    1897             :   ViewStride()                             = default;
    1898             :   ViewStride(const ViewStride&)            = default;
    1899             :   ViewStride& operator=(const ViewStride&) = default;
    1900             : 
    1901             :   KOKKOS_INLINE_FUNCTION
    1902             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t, size_t, size_t, size_t,
    1903             :                        size_t, size_t)
    1904             :       : S0(aS0), S1(aS1) {}
    1905             : };
    1906             : 
    1907             : template <>
    1908             : struct ViewStride<3> {
    1909             :   size_t S0, S1, S2;
    1910             :   static constexpr size_t S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0;
    1911             : 
    1912             :   ViewStride()                             = default;
    1913             :   ViewStride(const ViewStride&)            = default;
    1914             :   ViewStride& operator=(const ViewStride&) = default;
    1915             : 
    1916             :   KOKKOS_INLINE_FUNCTION
    1917             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t aS2, size_t, size_t,
    1918             :                        size_t, size_t, size_t)
    1919             :       : S0(aS0), S1(aS1), S2(aS2) {}
    1920             : };
    1921             : 
    1922             : template <>
    1923             : struct ViewStride<4> {
    1924             :   size_t S0, S1, S2, S3;
    1925             :   static constexpr size_t S4 = 0, S5 = 0, S6 = 0, S7 = 0;
    1926             : 
    1927             :   ViewStride()                             = default;
    1928             :   ViewStride(const ViewStride&)            = default;
    1929             :   ViewStride& operator=(const ViewStride&) = default;
    1930             : 
    1931             :   KOKKOS_INLINE_FUNCTION
    1932             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t aS2, size_t aS3, size_t,
    1933             :                        size_t, size_t, size_t)
    1934             :       : S0(aS0), S1(aS1), S2(aS2), S3(aS3) {}
    1935             : };
    1936             : 
    1937             : template <>
    1938             : struct ViewStride<5> {
    1939             :   size_t S0, S1, S2, S3, S4;
    1940             :   static constexpr size_t S5 = 0, S6 = 0, S7 = 0;
    1941             : 
    1942             :   ViewStride()                             = default;
    1943             :   ViewStride(const ViewStride&)            = default;
    1944             :   ViewStride& operator=(const ViewStride&) = default;
    1945             : 
    1946             :   KOKKOS_INLINE_FUNCTION
    1947             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t aS2, size_t aS3,
    1948             :                        size_t aS4, size_t, size_t, size_t)
    1949             :       : S0(aS0), S1(aS1), S2(aS2), S3(aS3), S4(aS4) {}
    1950             : };
    1951             : 
    1952             : template <>
    1953             : struct ViewStride<6> {
    1954             :   size_t S0, S1, S2, S3, S4, S5;
    1955             :   static constexpr size_t S6 = 0, S7 = 0;
    1956             : 
    1957             :   ViewStride()                             = default;
    1958             :   ViewStride(const ViewStride&)            = default;
    1959             :   ViewStride& operator=(const ViewStride&) = default;
    1960             : 
    1961             :   KOKKOS_INLINE_FUNCTION
    1962             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t aS2, size_t aS3,
    1963             :                        size_t aS4, size_t aS5, size_t, size_t)
    1964             :       : S0(aS0), S1(aS1), S2(aS2), S3(aS3), S4(aS4), S5(aS5) {}
    1965             : };
    1966             : 
    1967             : template <>
    1968             : struct ViewStride<7> {
    1969             :   size_t S0, S1, S2, S3, S4, S5, S6;
    1970             :   static constexpr size_t S7 = 0;
    1971             : 
    1972             :   ViewStride()                             = default;
    1973             :   ViewStride(const ViewStride&)            = default;
    1974             :   ViewStride& operator=(const ViewStride&) = default;
    1975             : 
    1976             :   KOKKOS_INLINE_FUNCTION
    1977             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t aS2, size_t aS3,
    1978             :                        size_t aS4, size_t aS5, size_t aS6, size_t)
    1979             :       : S0(aS0), S1(aS1), S2(aS2), S3(aS3), S4(aS4), S5(aS5), S6(aS6) {}
    1980             : };
    1981             : 
    1982             : template <>
    1983             : struct ViewStride<8> {
    1984             :   size_t S0, S1, S2, S3, S4, S5, S6, S7;
    1985             : 
    1986             :   ViewStride()                             = default;
    1987             :   ViewStride(const ViewStride&)            = default;
    1988             :   ViewStride& operator=(const ViewStride&) = default;
    1989             : 
    1990             :   KOKKOS_INLINE_FUNCTION
    1991             :   constexpr ViewStride(size_t aS0, size_t aS1, size_t aS2, size_t aS3,
    1992             :                        size_t aS4, size_t aS5, size_t aS6, size_t aS7)
    1993             :       : S0(aS0),
    1994             :         S1(aS1),
    1995             :         S2(aS2),
    1996             :         S3(aS3),
    1997             :         S4(aS4),
    1998             :         S5(aS5),
    1999             :         S6(aS6),
    2000             :         S7(aS7) {}
    2001             : };
    2002             : 
    2003             : template <class Dimension>
    2004             : struct ViewOffset<Dimension, Kokkos::LayoutStride, void> {
    2005             :  private:
    2006             :   using stride_type = ViewStride<Dimension::rank>;
    2007             : 
    2008             :  public:
    2009             :   using is_mapping_plugin = std::true_type;
    2010             :   using is_regular        = std::true_type;
    2011             : 
    2012             :   using size_type      = size_t;
    2013             :   using dimension_type = Dimension;
    2014             :   using array_layout   = Kokkos::LayoutStride;
    2015             : 
    2016             :   dimension_type m_dim;
    2017             :   stride_type m_stride;
    2018             : 
    2019             :   //----------------------------------------
    2020             : 
    2021             :   // rank 1
    2022             :   template <typename I0>
    2023             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0) const {
    2024             :     return i0 * m_stride.S0;
    2025             :   }
    2026             : 
    2027             :   // rank 2
    2028             :   template <typename I0, typename I1>
    2029             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    2030             :                                                         I1 const& i1) const {
    2031             :     return i0 * m_stride.S0 + i1 * m_stride.S1;
    2032             :   }
    2033             : 
    2034             :   // rank 3
    2035             :   template <typename I0, typename I1, typename I2>
    2036             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    2037             :                                                         I1 const& i1,
    2038             :                                                         I2 const& i2) const {
    2039             :     return i0 * m_stride.S0 + i1 * m_stride.S1 + i2 * m_stride.S2;
    2040             :   }
    2041             : 
    2042             :   // rank 4
    2043             :   template <typename I0, typename I1, typename I2, typename I3>
    2044             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    2045             :                                                         I1 const& i1,
    2046             :                                                         I2 const& i2,
    2047             :                                                         I3 const& i3) const {
    2048             :     return i0 * m_stride.S0 + i1 * m_stride.S1 + i2 * m_stride.S2 +
    2049             :            i3 * m_stride.S3;
    2050             :   }
    2051             : 
    2052             :   // rank 5
    2053             :   template <typename I0, typename I1, typename I2, typename I3, typename I4>
    2054             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(I0 const& i0,
    2055             :                                                         I1 const& i1,
    2056             :                                                         I2 const& i2,
    2057             :                                                         I3 const& i3,
    2058             :                                                         I4 const& i4) const {
    2059             :     return i0 * m_stride.S0 + i1 * m_stride.S1 + i2 * m_stride.S2 +
    2060             :            i3 * m_stride.S3 + i4 * m_stride.S4;
    2061             :   }
    2062             : 
    2063             :   // rank 6
    2064             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    2065             :             typename I5>
    2066             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    2067             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    2068             :       I5 const& i5) const {
    2069             :     return i0 * m_stride.S0 + i1 * m_stride.S1 + i2 * m_stride.S2 +
    2070             :            i3 * m_stride.S3 + i4 * m_stride.S4 + i5 * m_stride.S5;
    2071             :   }
    2072             : 
    2073             :   // rank 7
    2074             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    2075             :             typename I5, typename I6>
    2076             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    2077             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    2078             :       I5 const& i5, I6 const& i6) const {
    2079             :     return i0 * m_stride.S0 + i1 * m_stride.S1 + i2 * m_stride.S2 +
    2080             :            i3 * m_stride.S3 + i4 * m_stride.S4 + i5 * m_stride.S5 +
    2081             :            i6 * m_stride.S6;
    2082             :   }
    2083             : 
    2084             :   // rank 8
    2085             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    2086             :             typename I5, typename I6, typename I7>
    2087             :   KOKKOS_INLINE_FUNCTION constexpr size_type operator()(
    2088             :       I0 const& i0, I1 const& i1, I2 const& i2, I3 const& i3, I4 const& i4,
    2089             :       I5 const& i5, I6 const& i6, I7 const& i7) const {
    2090             :     return i0 * m_stride.S0 + i1 * m_stride.S1 + i2 * m_stride.S2 +
    2091             :            i3 * m_stride.S3 + i4 * m_stride.S4 + i5 * m_stride.S5 +
    2092             :            i6 * m_stride.S6 + i7 * m_stride.S7;
    2093             :   }
    2094             : 
    2095             :   //----------------------------------------
    2096             : 
    2097             :   KOKKOS_INLINE_FUNCTION
    2098             :   constexpr array_layout layout() const {
    2099             :     constexpr auto r = dimension_type::rank;
    2100             :     return array_layout((r > 0 ? m_dim.N0 : KOKKOS_INVALID_INDEX), m_stride.S0,
    2101             :                         (r > 1 ? m_dim.N1 : KOKKOS_INVALID_INDEX), m_stride.S1,
    2102             :                         (r > 2 ? m_dim.N2 : KOKKOS_INVALID_INDEX), m_stride.S2,
    2103             :                         (r > 3 ? m_dim.N3 : KOKKOS_INVALID_INDEX), m_stride.S3,
    2104             :                         (r > 4 ? m_dim.N4 : KOKKOS_INVALID_INDEX), m_stride.S4,
    2105             :                         (r > 5 ? m_dim.N5 : KOKKOS_INVALID_INDEX), m_stride.S5,
    2106             :                         (r > 6 ? m_dim.N6 : KOKKOS_INVALID_INDEX), m_stride.S6,
    2107             :                         (r > 7 ? m_dim.N7 : KOKKOS_INVALID_INDEX), m_stride.S7);
    2108             :   }
    2109             : 
    2110             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
    2111             :     return m_dim.N0;
    2112             :   }
    2113             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const {
    2114             :     return m_dim.N1;
    2115             :   }
    2116             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const {
    2117             :     return m_dim.N2;
    2118             :   }
    2119             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const {
    2120             :     return m_dim.N3;
    2121             :   }
    2122             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const {
    2123             :     return m_dim.N4;
    2124             :   }
    2125             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const {
    2126             :     return m_dim.N5;
    2127             :   }
    2128             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const {
    2129             :     return m_dim.N6;
    2130             :   }
    2131             :   KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const {
    2132             :     return m_dim.N7;
    2133             :   }
    2134             : 
    2135             :   /* Cardinality of the domain index space */
    2136             :   KOKKOS_INLINE_FUNCTION
    2137             :   constexpr size_type size() const {
    2138             :     return dimension_type::rank == 0
    2139             :                ? 1
    2140             :                : size_type(m_dim.N0) * m_dim.N1 * m_dim.N2 * m_dim.N3 *
    2141             :                      m_dim.N4 * m_dim.N5 * m_dim.N6 * m_dim.N7;
    2142             :   }
    2143             : 
    2144             :  private:
    2145             :   KOKKOS_INLINE_FUNCTION
    2146             :   static constexpr size_type Max(size_type lhs, size_type rhs) {
    2147             :     return lhs < rhs ? rhs : lhs;
    2148             :   }
    2149             : 
    2150             :  public:
    2151             :   /* Span of the range space, largest stride * dimension */
    2152             :   KOKKOS_INLINE_FUNCTION
    2153             :   constexpr size_type span() const {
    2154             :     return dimension_type::rank == 0
    2155             :                ? 1
    2156             :                : (size() == size_type(0)
    2157             :                       ? size_type(0)
    2158             :                       : Max(m_dim.N0 * m_stride.S0,
    2159             :                             Max(m_dim.N1 * m_stride.S1,
    2160             :                                 Max(m_dim.N2 * m_stride.S2,
    2161             :                                     Max(m_dim.N3 * m_stride.S3,
    2162             :                                         Max(m_dim.N4 * m_stride.S4,
    2163             :                                             Max(m_dim.N5 * m_stride.S5,
    2164             :                                                 Max(m_dim.N6 * m_stride.S6,
    2165             :                                                     m_dim.N7 *
    2166             :                                                         m_stride.S7))))))));
    2167             :   }
    2168             : 
    2169             :   KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
    2170             :     return span() == size();
    2171             :   }
    2172             : 
    2173             :   /* Strides of dimensions */
    2174             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const {
    2175             :     return m_stride.S0;
    2176             :   }
    2177             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const {
    2178             :     return m_stride.S1;
    2179             :   }
    2180             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const {
    2181             :     return m_stride.S2;
    2182             :   }
    2183             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const {
    2184             :     return m_stride.S3;
    2185             :   }
    2186             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const {
    2187             :     return m_stride.S4;
    2188             :   }
    2189             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const {
    2190             :     return m_stride.S5;
    2191             :   }
    2192             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const {
    2193             :     return m_stride.S6;
    2194             :   }
    2195             :   KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const {
    2196             :     return m_stride.S7;
    2197             :   }
    2198             : 
    2199             :   // Fill the target unbounded array s with the stride.
    2200             :   // This method differs from stride() in that it does not write the total
    2201             :   // length to the last index of the array. Preconditions: s must be an array of
    2202             :   // dimension_type::rank elements
    2203             :   // The version of clang-format in CI fails from maybe_unused
    2204             :   // clang-format off
    2205             :   template <typename iType>
    2206             :   KOKKOS_INLINE_FUNCTION iType
    2207             :   stride_fill([[maybe_unused]] iType* const s) const {
    2208             :     if constexpr (0 < dimension_type::rank) {
    2209             :       s[0] = m_stride.S0;
    2210             :     }
    2211             :     if constexpr (1 < dimension_type::rank) {
    2212             :       s[1] = m_stride.S1;
    2213             :     }
    2214             :     if constexpr (2 < dimension_type::rank) {
    2215             :       s[2] = m_stride.S2;
    2216             :     }
    2217             :     if constexpr (3 < dimension_type::rank) {
    2218             :       s[3] = m_stride.S3;
    2219             :     }
    2220             :     if constexpr (4 < dimension_type::rank) {
    2221             :       s[4] = m_stride.S4;
    2222             :     }
    2223             :     if constexpr (5 < dimension_type::rank) {
    2224             :       s[5] = m_stride.S5;
    2225             :     }
    2226             :     if constexpr (6 < dimension_type::rank) {
    2227             :       s[6] = m_stride.S6;
    2228             :     }
    2229             :     if constexpr (7 < dimension_type::rank) {
    2230             :       s[7] = m_stride.S7;
    2231             :     }
    2232             :     return span();
    2233             :   }
    2234             :   // clang-format on
    2235             : 
    2236             :   // Fill the target unbounded array s with the stride and the total spanned
    2237             :   // size. This method differs from stride_fill() in that it writes the total
    2238             :   // spanned size to the last index of the array. Preconditions: s must be an
    2239             :   // array of dimension_type::rank + 1 elements
    2240             :   template <typename iType>
    2241             :   KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
    2242             :     s[dimension_type::rank] = stride_fill(s);
    2243             :   }
    2244             : 
    2245             :   //----------------------------------------
    2246             :   // MSVC (16.5.5) + CUDA (10.2) did not generate the defaulted functions
    2247             :   // correct and errors out during compilation. Same for the other places where
    2248             :   // I changed this.
    2249             : 
    2250             : #ifdef KOKKOS_IMPL_WINDOWS_CUDA
    2251             :   KOKKOS_FUNCTION ViewOffset()
    2252             :       : m_dim(dimension_type()), m_stride(stride_type()) {}
    2253             :   KOKKOS_FUNCTION ViewOffset(const ViewOffset& src) {
    2254             :     m_dim    = src.m_dim;
    2255             :     m_stride = src.m_stride;
    2256             :   }
    2257             :   KOKKOS_FUNCTION ViewOffset& operator=(const ViewOffset& src) {
    2258             :     m_dim    = src.m_dim;
    2259             :     m_stride = src.m_stride;
    2260             :     return *this;
    2261             :   }
    2262             : #else
    2263             : 
    2264             :   ViewOffset()                             = default;
    2265             :   ViewOffset(const ViewOffset&)            = default;
    2266             :   ViewOffset& operator=(const ViewOffset&) = default;
    2267             : #endif
    2268             : 
    2269             :   KOKKOS_INLINE_FUNCTION
    2270             :   constexpr ViewOffset(std::integral_constant<unsigned, 0> const&,
    2271             :                        Kokkos::LayoutStride const& rhs)
    2272             :       : m_dim(rhs.dimension[0], rhs.dimension[1], rhs.dimension[2],
    2273             :               rhs.dimension[3], rhs.dimension[4], rhs.dimension[5],
    2274             :               rhs.dimension[6], rhs.dimension[7]),
    2275             :         m_stride(rhs.stride[0], rhs.stride[1], rhs.stride[2], rhs.stride[3],
    2276             :                  rhs.stride[4], rhs.stride[5], rhs.stride[6], rhs.stride[7]) {}
    2277             : 
    2278             :   template <class DimRHS, class LayoutRHS>
    2279             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    2280             :       const ViewOffset<DimRHS, LayoutRHS, void>& rhs)
    2281             :       : m_dim(rhs.m_dim.N0, rhs.m_dim.N1, rhs.m_dim.N2, rhs.m_dim.N3,
    2282             :               rhs.m_dim.N4, rhs.m_dim.N5, rhs.m_dim.N6, rhs.m_dim.N7),
    2283             :         m_stride(rhs.stride_0(), rhs.stride_1(), rhs.stride_2(), rhs.stride_3(),
    2284             :                  rhs.stride_4(), rhs.stride_5(), rhs.stride_6(),
    2285             :                  rhs.stride_7()) {
    2286             :     static_assert(int(DimRHS::rank) == int(dimension_type::rank),
    2287             :                   "ViewOffset assignment requires equal rank");
    2288             :     // Also requires equal static dimensions ...
    2289             :   }
    2290             : 
    2291             :   //----------------------------------------
    2292             :   // Subview construction
    2293             : 
    2294             :  private:
    2295             :   template <class DimRHS, class LayoutRHS>
    2296             :   KOKKOS_INLINE_FUNCTION static constexpr size_t stride(
    2297             :       unsigned r, const ViewOffset<DimRHS, LayoutRHS, void>& rhs) {
    2298             :     return r > 7
    2299             :                ? 0
    2300             :                : (r == 0
    2301             :                       ? rhs.stride_0()
    2302             :                       : (r == 1
    2303             :                              ? rhs.stride_1()
    2304             :                              : (r == 2
    2305             :                                     ? rhs.stride_2()
    2306             :                                     : (r == 3
    2307             :                                            ? rhs.stride_3()
    2308             :                                            : (r == 4
    2309             :                                                   ? rhs.stride_4()
    2310             :                                                   : (r == 5
    2311             :                                                          ? rhs.stride_5()
    2312             :                                                          : (r == 6
    2313             :                                                                 ? rhs.stride_6()
    2314             :                                                                 : rhs.stride_7())))))));
    2315             :   }
    2316             : 
    2317             :  public:
    2318             :   template <class DimRHS, class LayoutRHS>
    2319             :   KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
    2320             :       const ViewOffset<DimRHS, LayoutRHS, void>& rhs,
    2321             :       const SubviewExtents<DimRHS::rank, dimension_type::rank>& sub)
    2322             :       // range_extent(r) returns 0 when dimension_type::rank <= r
    2323             :       : m_dim(sub.range_extent(0), sub.range_extent(1), sub.range_extent(2),
    2324             :               sub.range_extent(3), sub.range_extent(4), sub.range_extent(5),
    2325             :               sub.range_extent(6), sub.range_extent(7))
    2326             :         // range_index(r) returns ~0u when dimension_type::rank <= r
    2327             :         ,
    2328             :         m_stride(
    2329             :             stride(sub.range_index(0), rhs), stride(sub.range_index(1), rhs),
    2330             :             stride(sub.range_index(2), rhs), stride(sub.range_index(3), rhs),
    2331             :             stride(sub.range_index(4), rhs), stride(sub.range_index(5), rhs),
    2332             :             stride(sub.range_index(6), rhs), stride(sub.range_index(7), rhs)) {}
    2333             : };
    2334             : 
    2335             : }  // namespace Impl
    2336             : }  // namespace Kokkos
    2337             : 
    2338             : //----------------------------------------------------------------------------
    2339             : //----------------------------------------------------------------------------
    2340             : 
    2341             : namespace Kokkos {
    2342             : namespace Impl {
    2343             : 
    2344             : /** \brief  ViewDataHandle provides the type of the 'data handle' which the view
    2345             :  *          uses to access data with the [] operator. It also provides
    2346             :  *          an allocate function and a function to extract a raw ptr from the
    2347             :  *          data handle. ViewDataHandle also defines an enum ReferenceAble which
    2348             :  *          specifies whether references/pointers to elements can be taken and a
    2349             :  *          'return_type' which is what the view operators will give back.
    2350             :  *          Specialisation of this object allows three things depending
    2351             :  *          on ViewTraits and compiler options:
    2352             :  *          (i)   Use special allocator (e.g. huge pages/small pages and pinned
    2353             :  * memory) (ii)  Use special data handle type (e.g. add Cuda Texture Object)
    2354             :  *          (iii) Use special access intrinsics (e.g. texture fetch and
    2355             :  * non-caching loads)
    2356             :  */
    2357             : template <class Traits, class Enable = void>
    2358             : struct ViewDataHandle {
    2359             :   using value_type  = typename Traits::value_type;
    2360             :   using handle_type = typename Traits::value_type*;
    2361             :   using return_type = typename Traits::value_type&;
    2362             :   using track_type  = Kokkos::Impl::SharedAllocationTracker;
    2363             : 
    2364             :   KOKKOS_INLINE_FUNCTION
    2365             :   static handle_type assign(value_type* arg_data_ptr,
    2366             :                             track_type const& /*arg_tracker*/) {
    2367             :     return handle_type(arg_data_ptr);
    2368             :   }
    2369             : 
    2370             :   KOKKOS_INLINE_FUNCTION
    2371             :   static handle_type assign(handle_type const arg_data_ptr, size_t offset) {
    2372             :     return handle_type(arg_data_ptr + offset);
    2373             :   }
    2374             : };
    2375             : 
    2376             : template <class Traits>
    2377             : struct ViewDataHandle<
    2378             :     Traits,
    2379             :     std::enable_if_t<(std::is_same_v<typename Traits::non_const_value_type,
    2380             :                                      typename Traits::value_type> &&
    2381             :                       std::is_void_v<typename Traits::specialize> &&
    2382             :                       Traits::memory_traits::is_atomic)>> {
    2383             :   using value_type  = typename Traits::value_type;
    2384             :   using handle_type = typename Kokkos::Impl::AtomicViewDataHandle<Traits>;
    2385             :   using return_type = typename Kokkos::Impl::AtomicDataElement<Traits>;
    2386             :   using track_type  = Kokkos::Impl::SharedAllocationTracker;
    2387             : 
    2388             :   KOKKOS_INLINE_FUNCTION
    2389             :   static handle_type assign(value_type* arg_data_ptr,
    2390             :                             track_type const& /*arg_tracker*/) {
    2391             :     return handle_type(arg_data_ptr);
    2392             :   }
    2393             : 
    2394             :   template <class SrcHandleType>
    2395             :   KOKKOS_INLINE_FUNCTION static handle_type assign(
    2396             :       const SrcHandleType& arg_handle, size_t offset) {
    2397             :     return handle_type(arg_handle + offset);
    2398             :   }
    2399             : };
    2400             : 
    2401             : template <class Traits>
    2402             : struct ViewDataHandle<
    2403             :     Traits, std::enable_if_t<(std::is_void_v<typename Traits::specialize> &&
    2404             :                               (!Traits::memory_traits::is_aligned) &&
    2405             :                               Traits::memory_traits::is_restrict &&
    2406             :                               (!Traits::memory_traits::is_atomic))>> {
    2407             :   using value_type  = typename Traits::value_type;
    2408             :   using handle_type = typename Traits::value_type* KOKKOS_RESTRICT;
    2409             :   using return_type = typename Traits::value_type& KOKKOS_RESTRICT;
    2410             :   using track_type  = Kokkos::Impl::SharedAllocationTracker;
    2411             : 
    2412             :   KOKKOS_INLINE_FUNCTION
    2413             :   static value_type* assign(value_type* arg_data_ptr,
    2414             :                             track_type const& /*arg_tracker*/) {
    2415             :     return (value_type*)(arg_data_ptr);
    2416             :   }
    2417             : 
    2418             :   KOKKOS_INLINE_FUNCTION
    2419             :   static value_type* assign(handle_type const arg_data_ptr, size_t offset) {
    2420             :     return (value_type*)(arg_data_ptr + offset);
    2421             :   }
    2422             : };
    2423             : 
    2424             : template <class Traits>
    2425             : struct ViewDataHandle<
    2426             :     Traits, std::enable_if_t<(std::is_void_v<typename Traits::specialize> &&
    2427             :                               Traits::memory_traits::is_aligned &&
    2428             :                               (!Traits::memory_traits::is_restrict) &&
    2429             :                               (!Traits::memory_traits::is_atomic))>> {
    2430             :   using value_type = typename Traits::value_type;
    2431             :   // typedef work-around for intel compilers error #3186: expected typedef
    2432             :   // declaration
    2433             :   // NOLINTNEXTLINE(modernize-use-using)
    2434             :   typedef value_type* KOKKOS_IMPL_ALIGN_PTR(KOKKOS_MEMORY_ALIGNMENT)
    2435             :       handle_type;
    2436             :   using return_type = typename Traits::value_type&;
    2437             :   using track_type  = Kokkos::Impl::SharedAllocationTracker;
    2438             : 
    2439             :   KOKKOS_INLINE_FUNCTION
    2440             :   static handle_type assign(value_type* arg_data_ptr,
    2441             :                             track_type const& /*arg_tracker*/) {
    2442             :     if (reinterpret_cast<uintptr_t>(arg_data_ptr) % Impl::MEMORY_ALIGNMENT) {
    2443             :       Kokkos::abort(
    2444             :           "Assigning NonAligned View or Pointer to Kokkos::View with Aligned "
    2445             :           "attribute");
    2446             :     }
    2447             :     return handle_type(arg_data_ptr);
    2448             :   }
    2449             : 
    2450             :   KOKKOS_INLINE_FUNCTION
    2451             :   static handle_type assign(handle_type const arg_data_ptr, size_t offset) {
    2452             :     if (reinterpret_cast<uintptr_t>(arg_data_ptr + offset) %
    2453             :         Impl::MEMORY_ALIGNMENT) {
    2454             :       Kokkos::abort(
    2455             :           "Assigning NonAligned View or Pointer to Kokkos::View with Aligned "
    2456             :           "attribute");
    2457             :     }
    2458             :     return handle_type(arg_data_ptr + offset);
    2459             :   }
    2460             : };
    2461             : 
    2462             : template <class Traits>
    2463             : struct ViewDataHandle<
    2464             :     Traits, std::enable_if_t<(std::is_void_v<typename Traits::specialize> &&
    2465             :                               Traits::memory_traits::is_aligned &&
    2466             :                               Traits::memory_traits::is_restrict &&
    2467             :                               (!Traits::memory_traits::is_atomic))>> {
    2468             :   using value_type = typename Traits::value_type;
    2469             :   // typedef work-around for intel compilers error #3186: expected typedef
    2470             :   // declaration
    2471             :   // NOLINTNEXTLINE(modernize-use-using)
    2472             :   typedef value_type* KOKKOS_IMPL_ALIGN_PTR(KOKKOS_MEMORY_ALIGNMENT)
    2473             :       handle_type;
    2474             :   using return_type = typename Traits::value_type& KOKKOS_RESTRICT;
    2475             :   using track_type  = Kokkos::Impl::SharedAllocationTracker;
    2476             : 
    2477             :   KOKKOS_INLINE_FUNCTION
    2478             :   static value_type* assign(value_type* arg_data_ptr,
    2479             :                             track_type const& /*arg_tracker*/) {
    2480             :     if (reinterpret_cast<uintptr_t>(arg_data_ptr) % Impl::MEMORY_ALIGNMENT) {
    2481             :       Kokkos::abort(
    2482             :           "Assigning NonAligned View or Pointer to Kokkos::View with Aligned "
    2483             :           "attribute");
    2484             :     }
    2485             :     return (value_type*)(arg_data_ptr);
    2486             :   }
    2487             : 
    2488             :   KOKKOS_INLINE_FUNCTION
    2489             :   static value_type* assign(handle_type const arg_data_ptr, size_t offset) {
    2490             :     if (reinterpret_cast<uintptr_t>(arg_data_ptr + offset) %
    2491             :         Impl::MEMORY_ALIGNMENT) {
    2492             :       Kokkos::abort(
    2493             :           "Assigning NonAligned View or Pointer to Kokkos::View with Aligned "
    2494             :           "attribute");
    2495             :     }
    2496             :     return (value_type*)(arg_data_ptr + offset);
    2497             :   }
    2498             : };
    2499             : }  // namespace Impl
    2500             : }  // namespace Kokkos
    2501             : 
    2502             : //----------------------------------------------------------------------------
    2503             : //----------------------------------------------------------------------------
    2504             : 
    2505             : namespace Kokkos {
    2506             : namespace Impl {
    2507             : //----------------------------------------------------------------------------
    2508             : /** \brief  View mapping for non-specialized data type and standard layout */
    2509             : template <class Traits>
    2510             : class ViewMapping<
    2511             :     Traits, std::enable_if_t<(std::is_void_v<typename Traits::specialize> &&
    2512             :                               ViewOffset<typename Traits::dimension,
    2513             :                                          typename Traits::array_layout,
    2514             :                                          void>::is_mapping_plugin::value)>> {
    2515             :  public:
    2516             :   using offset_type = ViewOffset<typename Traits::dimension,
    2517             :                                  typename Traits::array_layout, void>;
    2518             : 
    2519             :   using handle_type = typename ViewDataHandle<Traits>::handle_type;
    2520             : 
    2521             :   handle_type m_impl_handle;
    2522             :   offset_type m_impl_offset;
    2523             : 
    2524             :  private:
    2525             :   template <class, class...>
    2526             :   friend class ViewMapping;
    2527             : 
    2528             :   KOKKOS_INLINE_FUNCTION
    2529             :   ViewMapping(const handle_type& arg_handle, const offset_type& arg_offset)
    2530             :       : m_impl_handle(arg_handle), m_impl_offset(arg_offset) {}
    2531             : 
    2532             :  public:
    2533             :   using printable_label_typedef = void;
    2534             :   enum { is_managed = Traits::is_managed };
    2535             : 
    2536             :   //----------------------------------------
    2537             :   // Domain dimensions
    2538             : 
    2539             :   static constexpr unsigned Rank = Traits::dimension::rank;
    2540             : 
    2541             :   template <typename iType>
    2542   106864929 :   KOKKOS_INLINE_FUNCTION constexpr size_t extent(const iType& r) const {
    2543   106864929 :     return m_impl_offset.m_dim.extent(r);
    2544             :   }
    2545             : 
    2546             :   static KOKKOS_INLINE_FUNCTION constexpr size_t static_extent(
    2547             :       const unsigned r) noexcept {
    2548             :     using dim_type = typename offset_type::dimension_type;
    2549             :     return dim_type::static_extent(r);
    2550             :   }
    2551             : 
    2552             :   KOKKOS_INLINE_FUNCTION constexpr typename Traits::array_layout layout()
    2553             :       const {
    2554             :     return m_impl_offset.layout();
    2555             :   }
    2556             : 
    2557     1378872 :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const {
    2558     1378872 :     return m_impl_offset.dimension_0();
    2559             :   }
    2560             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const {
    2561             :     return m_impl_offset.dimension_1();
    2562             :   }
    2563             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const {
    2564             :     return m_impl_offset.dimension_2();
    2565             :   }
    2566             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const {
    2567             :     return m_impl_offset.dimension_3();
    2568             :   }
    2569             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const {
    2570             :     return m_impl_offset.dimension_4();
    2571             :   }
    2572             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const {
    2573             :     return m_impl_offset.dimension_5();
    2574             :   }
    2575             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const {
    2576             :     return m_impl_offset.dimension_6();
    2577             :   }
    2578             :   KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const {
    2579             :     return m_impl_offset.dimension_7();
    2580             :   }
    2581             : 
    2582             :   // Is a regular layout with uniform striding for each index.
    2583             :   using is_regular = typename offset_type::is_regular;
    2584             : 
    2585             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const {
    2586             :     return m_impl_offset.stride_0();
    2587             :   }
    2588             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const {
    2589             :     return m_impl_offset.stride_1();
    2590             :   }
    2591             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const {
    2592             :     return m_impl_offset.stride_2();
    2593             :   }
    2594             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const {
    2595             :     return m_impl_offset.stride_3();
    2596             :   }
    2597             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const {
    2598             :     return m_impl_offset.stride_4();
    2599             :   }
    2600             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const {
    2601             :     return m_impl_offset.stride_5();
    2602             :   }
    2603             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const {
    2604             :     return m_impl_offset.stride_6();
    2605             :   }
    2606             :   KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const {
    2607             :     return m_impl_offset.stride_7();
    2608             :   }
    2609             : 
    2610             :   // Fill the target unbounded array s with the stride and the total spanned
    2611             :   // size. This method differs from stride_fill() in that it writes the total
    2612             :   // spanned size to the last index of the array. Preconditions: s must be an
    2613             :   // array of dimension_type::rank + 1 elements
    2614             :   template <typename iType>
    2615             :   KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
    2616             :     m_impl_offset.stride(s);
    2617             :   }
    2618             : 
    2619             :   // Fill the target unbounded array s with the stride.
    2620             :   // This method differs from stride() in that it does not write the total
    2621             :   // length to the last index of the array. Preconditions: s must be an array of
    2622             :   // dimension_type::rank elements
    2623             :   template <typename iType>
    2624             :   KOKKOS_INLINE_FUNCTION iType stride_fill(iType* const s) const {
    2625             :     return m_impl_offset.stride_fill(s);
    2626             :   }
    2627             : 
    2628             :   //----------------------------------------
    2629             :   // Range span
    2630             : 
    2631             :   /** \brief  Span of the mapped range */
    2632             :   KOKKOS_INLINE_FUNCTION constexpr size_t span() const {
    2633             :     return m_impl_offset.span();
    2634             :   }
    2635             : 
    2636             :   /** \brief  Is the mapped range span contiguous */
    2637             :   KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
    2638             :     return m_impl_offset.span_is_contiguous();
    2639             :   }
    2640             : 
    2641             :   using reference_type = typename ViewDataHandle<Traits>::return_type;
    2642             :   using pointer_type   = typename Traits::value_type*;
    2643             : 
    2644             :   /** \brief  Query raw pointer to memory */
    2645             :   KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
    2646             :     return m_impl_handle;
    2647             :   }
    2648             : 
    2649             :   //----------------------------------------
    2650             :   // The View class performs all rank and bounds checking before
    2651             :   // calling these element reference methods.
    2652             : 
    2653             :   KOKKOS_FORCEINLINE_FUNCTION
    2654             :   reference_type reference() const { return m_impl_handle[0]; }
    2655             : 
    2656             :   template <typename I0>
    2657             :   KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
    2658             :       (std::is_integral_v<I0> &&
    2659             :        // if layout is neither stride nor irregular,
    2660             :        // then just use the handle directly
    2661             :        !(std::is_same_v<typename Traits::array_layout, Kokkos::LayoutStride> ||
    2662             :          !is_regular::value)),
    2663             :       reference_type>
    2664             :   reference(const I0& i0) const {
    2665             :     return m_impl_handle[i0];
    2666             :   }
    2667             : 
    2668             :   template <typename I0>
    2669             :   KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
    2670             :       (std::is_integral_v<I0> &&
    2671             :        // if the layout is strided or irregular, then
    2672             :        // we have to use the offset
    2673             :        (std::is_same_v<typename Traits::array_layout, Kokkos::LayoutStride> ||
    2674             :         !is_regular::value)),
    2675             :       reference_type>
    2676             :   reference(const I0& i0) const {
    2677             :     return m_impl_handle[m_impl_offset(i0)];
    2678             :   }
    2679             : 
    2680             :   template <typename I0, typename I1>
    2681             :   KOKKOS_FORCEINLINE_FUNCTION reference_type reference(const I0& i0,
    2682             :                                                        const I1& i1) const {
    2683             :     return m_impl_handle[m_impl_offset(i0, i1)];
    2684             :   }
    2685             : 
    2686             :   template <typename I0, typename I1, typename I2>
    2687             :   KOKKOS_FORCEINLINE_FUNCTION reference_type reference(const I0& i0,
    2688             :                                                        const I1& i1,
    2689             :                                                        const I2& i2) const {
    2690             :     return m_impl_handle[m_impl_offset(i0, i1, i2)];
    2691             :   }
    2692             : 
    2693             :   template <typename I0, typename I1, typename I2, typename I3>
    2694             :   KOKKOS_FORCEINLINE_FUNCTION reference_type
    2695             :   reference(const I0& i0, const I1& i1, const I2& i2, const I3& i3) const {
    2696             :     return m_impl_handle[m_impl_offset(i0, i1, i2, i3)];
    2697             :   }
    2698             : 
    2699             :   template <typename I0, typename I1, typename I2, typename I3, typename I4>
    2700             :   KOKKOS_FORCEINLINE_FUNCTION reference_type reference(const I0& i0,
    2701             :                                                        const I1& i1,
    2702             :                                                        const I2& i2,
    2703             :                                                        const I3& i3,
    2704             :                                                        const I4& i4) const {
    2705             :     return m_impl_handle[m_impl_offset(i0, i1, i2, i3, i4)];
    2706             :   }
    2707             : 
    2708             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    2709             :             typename I5>
    2710             :   KOKKOS_FORCEINLINE_FUNCTION reference_type
    2711             :   reference(const I0& i0, const I1& i1, const I2& i2, const I3& i3,
    2712             :             const I4& i4, const I5& i5) const {
    2713             :     return m_impl_handle[m_impl_offset(i0, i1, i2, i3, i4, i5)];
    2714             :   }
    2715             : 
    2716             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    2717             :             typename I5, typename I6>
    2718             :   KOKKOS_FORCEINLINE_FUNCTION reference_type
    2719             :   reference(const I0& i0, const I1& i1, const I2& i2, const I3& i3,
    2720             :             const I4& i4, const I5& i5, const I6& i6) const {
    2721             :     return m_impl_handle[m_impl_offset(i0, i1, i2, i3, i4, i5, i6)];
    2722             :   }
    2723             : 
    2724             :   template <typename I0, typename I1, typename I2, typename I3, typename I4,
    2725             :             typename I5, typename I6, typename I7>
    2726             :   KOKKOS_FORCEINLINE_FUNCTION reference_type
    2727             :   reference(const I0& i0, const I1& i1, const I2& i2, const I3& i3,
    2728             :             const I4& i4, const I5& i5, const I6& i6, const I7& i7) const {
    2729             :     return m_impl_handle[m_impl_offset(i0, i1, i2, i3, i4, i5, i6, i7)];
    2730             :   }
    2731             : 
    2732             :   //----------------------------------------
    2733             : 
    2734             :  private:
    2735             :   enum { MemorySpanMask = 8 - 1 /* Force alignment on 8 byte boundary */ };
    2736             :   enum { MemorySpanSize = sizeof(typename Traits::value_type) };
    2737             : 
    2738             :  public:
    2739             :   /** \brief  Span, in bytes, of the referenced memory */
    2740             :   KOKKOS_INLINE_FUNCTION constexpr size_t memory_span() const {
    2741             :     return (m_impl_offset.span() * sizeof(typename Traits::value_type) +
    2742             :             MemorySpanMask) &
    2743             :            ~size_t(MemorySpanMask);
    2744             :   }
    2745             : 
    2746             :   //----------------------------------------
    2747             : 
    2748             :   KOKKOS_DEFAULTED_FUNCTION ~ViewMapping() = default;
    2749             :   KOKKOS_INLINE_FUNCTION ViewMapping() : m_impl_handle(), m_impl_offset() {}
    2750             : 
    2751             :   KOKKOS_DEFAULTED_FUNCTION ViewMapping(const ViewMapping&) = default;
    2752             :   KOKKOS_DEFAULTED_FUNCTION ViewMapping& operator=(const ViewMapping&) =
    2753             :       default;
    2754             : 
    2755             :   KOKKOS_DEFAULTED_FUNCTION ViewMapping(ViewMapping&&)            = default;
    2756             :   KOKKOS_DEFAULTED_FUNCTION ViewMapping& operator=(ViewMapping&&) = default;
    2757             : 
    2758             :   //----------------------------------------
    2759             : 
    2760             :   /**\brief  Span, in bytes, of the required memory */
    2761             :   KOKKOS_INLINE_FUNCTION
    2762             :   static constexpr size_t memory_span(
    2763             :       typename Traits::array_layout const& arg_layout) {
    2764             :     using padding = std::integral_constant<unsigned int, 0>;
    2765             :     return (offset_type(padding(), arg_layout).span() * MemorySpanSize +
    2766             :             MemorySpanMask) &
    2767             :            ~size_t(MemorySpanMask);
    2768             :   }
    2769             : 
    2770             :   /**\brief  Wrap a span of memory */
    2771             :   template <class... P>
    2772             :   KOKKOS_INLINE_FUNCTION ViewMapping(
    2773             :       Kokkos::Impl::ViewCtorProp<P...> const& arg_prop,
    2774             :       typename Traits::array_layout const& arg_layout)
    2775             :       : m_impl_handle(Impl::get_property<Impl::PointerTag>(arg_prop)),
    2776             :         m_impl_offset(std::integral_constant<unsigned, 0>(), arg_layout) {}
    2777             : 
    2778             :   /**\brief  Assign data */
    2779             :   KOKKOS_INLINE_FUNCTION
    2780             :   void assign_data(pointer_type arg_ptr) {
    2781             :     m_impl_handle = handle_type(arg_ptr);
    2782             :   }
    2783             : 
    2784             :   //----------------------------------------
    2785             :   /*  Allocate and construct mapped array.
    2786             :    *  Allocate via shared allocation record and
    2787             :    *  return that record for allocation tracking.
    2788             :    */
    2789             :   template <class... P>
    2790             :   Kokkos::Impl::SharedAllocationRecord<>* allocate_shared(
    2791             :       Kokkos::Impl::ViewCtorProp<P...> const& arg_prop,
    2792             :       typename Traits::array_layout const& arg_layout,
    2793             :       bool execution_space_specified) {
    2794             :     using alloc_prop = Kokkos::Impl::ViewCtorProp<P...>;
    2795             : 
    2796             :     using execution_space = typename alloc_prop::execution_space;
    2797             :     using memory_space    = typename Traits::memory_space;
    2798             :     static_assert(
    2799             :         SpaceAccessibility<execution_space, memory_space>::accessible);
    2800             :     using device_type  = Kokkos::Device<execution_space, memory_space>;
    2801             :     using value_type   = typename Traits::value_type;
    2802             :     using functor_type = std::conditional_t<
    2803             :         alloc_prop::sequential_host_init,
    2804             :         ViewValueFunctorSequentialHostInit<device_type, value_type>,
    2805             :         ViewValueFunctor<device_type, value_type>>;
    2806             :     using record_type =
    2807             :         Kokkos::Impl::SharedAllocationRecord<memory_space, functor_type>;
    2808             : 
    2809             :     // Query the mapping for byte-size of allocation.
    2810             :     // If padding is allowed then pass in sizeof value type
    2811             :     // for padding computation.
    2812             :     using padding = std::integral_constant<
    2813             :         unsigned int, alloc_prop::allow_padding ? sizeof(value_type) : 0>;
    2814             : 
    2815             :     m_impl_offset = offset_type(padding(), arg_layout);
    2816             : 
    2817             :     const size_t alloc_size =
    2818             :         (m_impl_offset.span() * MemorySpanSize + MemorySpanMask) &
    2819             :         ~size_t(MemorySpanMask);
    2820             :     const std::string& alloc_name =
    2821             :         Impl::get_property<Impl::LabelTag>(arg_prop);
    2822             :     const execution_space& exec_space =
    2823             :         Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop);
    2824             :     const memory_space& mem_space =
    2825             :         Impl::get_property<Impl::MemorySpaceTag>(arg_prop);
    2826             : 
    2827             :     // Create shared memory tracking record with allocate memory from the memory
    2828             :     // space
    2829             :     record_type* const record =
    2830             :         execution_space_specified
    2831             :             ? record_type::allocate(exec_space, mem_space, alloc_name,
    2832             :                                     alloc_size)
    2833             :             : record_type::allocate(mem_space, alloc_name, alloc_size);
    2834             : 
    2835             :     m_impl_handle = handle_type(reinterpret_cast<pointer_type>(record->data()));
    2836             : 
    2837             :     functor_type functor =
    2838             :         execution_space_specified
    2839             :             ? functor_type(exec_space, (value_type*)m_impl_handle,
    2840             :                            m_impl_offset.span(), alloc_name)
    2841             :             : functor_type((value_type*)m_impl_handle, m_impl_offset.span(),
    2842             :                            alloc_name);
    2843             : 
    2844             :     //  Only initialize if the allocation is non-zero.
    2845             :     //  May be zero if one of the dimensions is zero.
    2846             :     if constexpr (alloc_prop::initialize)
    2847             :       if (alloc_size) {
    2848             :         // Assume destruction is only required when construction is requested.
    2849             :         // The ViewValueFunctor has both value construction and destruction
    2850             :         // operators.
    2851             :         record->m_destroy = std::move(functor);
    2852             : 
    2853             :         // Construct values
    2854             :         record->m_destroy.construct_shared_allocation();
    2855             :       }
    2856             : 
    2857             :     return record;
    2858             :   }
    2859             : };
    2860             : 
    2861             : //----------------------------------------------------------------------------
    2862             : //----------------------------------------------------------------------------
    2863             : /** \brief  Assign compatible default mappings */
    2864             : 
    2865             : template <class DstTraits, class SrcTraits>
    2866             : class ViewMapping<
    2867             :     DstTraits, SrcTraits,
    2868             :     std::enable_if_t<(
    2869             :         !(std::is_same_v<typename SrcTraits::array_layout,
    2870             :                          LayoutStride>)&&  // Added to have a new
    2871             :                                            // specialization for
    2872             :                                            // SrcType of
    2873             :                                            // LayoutStride
    2874             :         // default mappings
    2875             :         std::is_void_v<typename DstTraits::specialize> &&
    2876             :         std::is_void_v<typename SrcTraits::specialize> &&
    2877             :         (
    2878             :             // same layout
    2879             :             std::is_same_v<typename DstTraits::array_layout,
    2880             :                            typename SrcTraits::array_layout> ||
    2881             :             // known layout
    2882             :             ((std::is_same_v<typename DstTraits::array_layout,
    2883             :                              Kokkos::LayoutLeft> ||
    2884             :               std::is_same_v<typename DstTraits::array_layout,
    2885             :                              Kokkos::LayoutRight> ||
    2886             :               std::is_same_v<
    2887             :                   typename DstTraits::array_layout,
    2888             :                   Kokkos::LayoutStride>)&&(std::is_same_v<typename SrcTraits::
    2889             :                                                               array_layout,
    2890             :                                                           Kokkos::LayoutLeft> ||
    2891             :                                            std::is_same_v<
    2892             :                                                typename SrcTraits::array_layout,
    2893             :                                                Kokkos::LayoutRight> ||
    2894             :                                            std::is_same_v<
    2895             :                                                typename SrcTraits::array_layout,
    2896             :                                                Kokkos::LayoutStride>))))>> {
    2897             :  private:
    2898             :   enum {
    2899             :     is_assignable_space = Kokkos::Impl::MemorySpaceAccess<
    2900             :         typename DstTraits::memory_space,
    2901             :         typename SrcTraits::memory_space>::assignable
    2902             :   };
    2903             : 
    2904             :   enum {
    2905             :     is_assignable_value_type =
    2906             :         std::is_same_v<typename DstTraits::value_type,
    2907             :                        typename SrcTraits::value_type> ||
    2908             :         std::is_same_v<typename DstTraits::value_type,
    2909             :                        typename SrcTraits::const_value_type>
    2910             :   };
    2911             : 
    2912             :   enum {
    2913             :     is_assignable_dimension =
    2914             :         ViewDimensionAssignable<typename DstTraits::dimension,
    2915             :                                 typename SrcTraits::dimension>::value
    2916             :   };
    2917             : 
    2918             :   enum {
    2919             :     is_assignable_layout = std::is_same_v<typename DstTraits::array_layout,
    2920             :                                           typename SrcTraits::array_layout> ||
    2921             :                            std::is_same_v<typename DstTraits::array_layout,
    2922             :                                           Kokkos::LayoutStride> ||
    2923             :                            (DstTraits::dimension::rank == 0) ||
    2924             :                            (DstTraits::dimension::rank == 1)
    2925             :   };
    2926             : 
    2927             :  public:
    2928             :   enum {
    2929             :     is_assignable_data_type =
    2930             :         is_assignable_value_type && is_assignable_dimension
    2931             :   };
    2932             :   enum {
    2933             :     is_assignable = is_assignable_space && is_assignable_value_type &&
    2934             :                     is_assignable_dimension && is_assignable_layout
    2935             :   };
    2936             : 
    2937             :   using TrackType = Kokkos::Impl::SharedAllocationTracker;
    2938             :   using DstType   = ViewMapping<DstTraits, void>;
    2939             :   using SrcType   = ViewMapping<SrcTraits, void>;
    2940             : 
    2941             :   KOKKOS_INLINE_FUNCTION
    2942             :   static void assign(DstType& dst, const SrcType& src,
    2943             :                      const TrackType& src_track) {
    2944             :     static_assert(is_assignable_space,
    2945             :                   "View assignment must have compatible spaces");
    2946             : 
    2947             :     static_assert(
    2948             :         is_assignable_value_type,
    2949             :         "View assignment must have same value type or const = non-const");
    2950             : 
    2951             :     static_assert(is_assignable_dimension,
    2952             :                   "View assignment must have compatible dimensions");
    2953             : 
    2954             :     static_assert(
    2955             :         is_assignable_layout,
    2956             :         "View assignment must have compatible layout or have rank <= 1");
    2957             : 
    2958             :     using dst_offset_type = typename DstType::offset_type;
    2959             : 
    2960             :     if (size_t(DstTraits::dimension::rank_dynamic) <
    2961             :         size_t(SrcTraits::dimension::rank_dynamic)) {
    2962             :       using dst_dim   = typename DstTraits::dimension;
    2963             :       bool assignable = ((1 > DstTraits::dimension::rank_dynamic &&
    2964             :                           1 <= SrcTraits::dimension::rank_dynamic)
    2965             :                              ? dst_dim::ArgN0 == src.dimension_0()
    2966             :                              : true) &&
    2967             :                         ((2 > DstTraits::dimension::rank_dynamic &&
    2968             :                           2 <= SrcTraits::dimension::rank_dynamic)
    2969             :                              ? dst_dim::ArgN1 == src.dimension_1()
    2970             :                              : true) &&
    2971             :                         ((3 > DstTraits::dimension::rank_dynamic &&
    2972             :                           3 <= SrcTraits::dimension::rank_dynamic)
    2973             :                              ? dst_dim::ArgN2 == src.dimension_2()
    2974             :                              : true) &&
    2975             :                         ((4 > DstTraits::dimension::rank_dynamic &&
    2976             :                           4 <= SrcTraits::dimension::rank_dynamic)
    2977             :                              ? dst_dim::ArgN3 == src.dimension_3()
    2978             :                              : true) &&
    2979             :                         ((5 > DstTraits::dimension::rank_dynamic &&
    2980             :                           5 <= SrcTraits::dimension::rank_dynamic)
    2981             :                              ? dst_dim::ArgN4 == src.dimension_4()
    2982             :                              : true) &&
    2983             :                         ((6 > DstTraits::dimension::rank_dynamic &&
    2984             :                           6 <= SrcTraits::dimension::rank_dynamic)
    2985             :                              ? dst_dim::ArgN5 == src.dimension_5()
    2986             :                              : true) &&
    2987             :                         ((7 > DstTraits::dimension::rank_dynamic &&
    2988             :                           7 <= SrcTraits::dimension::rank_dynamic)
    2989             :                              ? dst_dim::ArgN6 == src.dimension_6()
    2990             :                              : true) &&
    2991             :                         ((8 > DstTraits::dimension::rank_dynamic &&
    2992             :                           8 <= SrcTraits::dimension::rank_dynamic)
    2993             :                              ? dst_dim::ArgN7 == src.dimension_7()
    2994             :                              : true);
    2995             :       if (!assignable)
    2996             :         Kokkos::abort(
    2997             :             "View Assignment: trying to assign runtime dimension to non "
    2998             :             "matching compile time dimension.");
    2999             :     }
    3000             :     dst.m_impl_offset = dst_offset_type(src.m_impl_offset);
    3001             :     dst.m_impl_handle = Kokkos::Impl::ViewDataHandle<DstTraits>::assign(
    3002             :         src.m_impl_handle, src_track);
    3003             :   }
    3004             : };
    3005             : 
    3006             : //----------------------------------------------------------------------------
    3007             : // Create new specialization for SrcType of LayoutStride. Runtime check for
    3008             : // compatible layout
    3009             : template <class DstTraits, class SrcTraits>
    3010             : class ViewMapping<
    3011             :     DstTraits, SrcTraits,
    3012             :     std::enable_if_t<(std::is_same_v<typename SrcTraits::array_layout,
    3013             :                                      Kokkos::LayoutStride> &&
    3014             :                       std::is_void_v<typename DstTraits::specialize> &&
    3015             :                       std::is_void_v<typename SrcTraits::specialize> &&
    3016             :                       (
    3017             :                           // same layout
    3018             :                           std::is_same_v<typename DstTraits::array_layout,
    3019             :                                          typename SrcTraits::array_layout> ||
    3020             :                           // known layout
    3021             :                           (std::is_same_v<typename DstTraits::array_layout,
    3022             :                                           Kokkos::LayoutLeft> ||
    3023             :                            std::is_same_v<typename DstTraits::array_layout,
    3024             :                                           Kokkos::LayoutRight> ||
    3025             :                            std::is_same_v<typename DstTraits::array_layout,
    3026             :                                           Kokkos::LayoutStride>)))>> {
    3027             :  private:
    3028             :   enum {
    3029             :     is_assignable_space = Kokkos::Impl::MemorySpaceAccess<
    3030             :         typename DstTraits::memory_space,
    3031             :         typename SrcTraits::memory_space>::assignable
    3032             :   };
    3033             : 
    3034             :   enum {
    3035             :     is_assignable_value_type =
    3036             :         std::is_same_v<typename DstTraits::value_type,
    3037             :                        typename SrcTraits::value_type> ||
    3038             :         std::is_same_v<typename DstTraits::value_type,
    3039             :                        typename SrcTraits::const_value_type>
    3040             :   };
    3041             : 
    3042             :   enum {
    3043             :     is_assignable_dimension =
    3044             :         ViewDimensionAssignable<typename DstTraits::dimension,
    3045             :                                 typename SrcTraits::dimension>::value
    3046             :   };
    3047             : 
    3048             :  public:
    3049             :   enum {
    3050             :     is_assignable_data_type =
    3051             :         is_assignable_value_type && is_assignable_dimension
    3052             :   };
    3053             :   enum {
    3054             :     is_assignable = is_assignable_space && is_assignable_value_type &&
    3055             :                     is_assignable_dimension
    3056             :   };
    3057             : 
    3058             :   using TrackType = Kokkos::Impl::SharedAllocationTracker;
    3059             :   using DstType   = ViewMapping<DstTraits, void>;
    3060             :   using SrcType   = ViewMapping<SrcTraits, void>;
    3061             : 
    3062             :   KOKKOS_INLINE_FUNCTION
    3063             :   static bool assignable_layout_check(DstType&,
    3064             :                                       const SrcType& src)  // Runtime check
    3065             :   {
    3066             :     size_t strides[9];
    3067             :     bool assignable = true;
    3068             :     src.stride(strides);
    3069             :     size_t exp_stride = 1;
    3070             :     if (std::is_same_v<typename DstTraits::array_layout, Kokkos::LayoutLeft>) {
    3071             :       for (int i = 0; i < (int)src.Rank; i++) {
    3072             :         if (i > 0) exp_stride *= src.extent(i - 1);
    3073             :         if (strides[i] != exp_stride) {
    3074             :           assignable = false;
    3075             :           break;
    3076             :         }
    3077             :       }
    3078             :     } else if (std::is_same_v<typename DstTraits::array_layout,
    3079             :                               Kokkos::LayoutRight>) {
    3080             :       for (int i = 0; i < (int)src.Rank; i++) {
    3081             :         if (i > 0) exp_stride *= src.extent(src.Rank - i);
    3082             :         if (strides[src.Rank - 1 - i] != exp_stride) {
    3083             :           assignable = false;
    3084             :           break;
    3085             :         }
    3086             :       }
    3087             :     }
    3088             :     return assignable;
    3089             :   }
    3090             : 
    3091             :   KOKKOS_INLINE_FUNCTION
    3092             :   static void assign(DstType& dst, const SrcType& src,
    3093             :                      const TrackType& src_track) {
    3094             :     static_assert(is_assignable_space,
    3095             :                   "View assignment must have compatible spaces");
    3096             : 
    3097             :     static_assert(
    3098             :         is_assignable_value_type,
    3099             :         "View assignment must have same value type or const = non-const");
    3100             : 
    3101             :     static_assert(is_assignable_dimension,
    3102             :                   "View assignment must have compatible dimensions");
    3103             : 
    3104             :     bool assignable_layout = assignable_layout_check(dst, src);  // Runtime
    3105             :                                                                  // check
    3106             :     if (!assignable_layout)
    3107             :       Kokkos::abort("View assignment must have compatible layouts\n");
    3108             : 
    3109             :     using dst_offset_type = typename DstType::offset_type;
    3110             : 
    3111             :     if (size_t(DstTraits::dimension::rank_dynamic) <
    3112             :         size_t(SrcTraits::dimension::rank_dynamic)) {
    3113             :       using dst_dim   = typename DstTraits::dimension;
    3114             :       bool assignable = ((1 > DstTraits::dimension::rank_dynamic &&
    3115             :                           1 <= SrcTraits::dimension::rank_dynamic)
    3116             :                              ? dst_dim::ArgN0 == src.dimension_0()
    3117             :                              : true) &&
    3118             :                         ((2 > DstTraits::dimension::rank_dynamic &&
    3119             :                           2 <= SrcTraits::dimension::rank_dynamic)
    3120             :                              ? dst_dim::ArgN1 == src.dimension_1()
    3121             :                              : true) &&
    3122             :                         ((3 > DstTraits::dimension::rank_dynamic &&
    3123             :                           3 <= SrcTraits::dimension::rank_dynamic)
    3124             :                              ? dst_dim::ArgN2 == src.dimension_2()
    3125             :                              : true) &&
    3126             :                         ((4 > DstTraits::dimension::rank_dynamic &&
    3127             :                           4 <= SrcTraits::dimension::rank_dynamic)
    3128             :                              ? dst_dim::ArgN3 == src.dimension_3()
    3129             :                              : true) &&
    3130             :                         ((5 > DstTraits::dimension::rank_dynamic &&
    3131             :                           5 <= SrcTraits::dimension::rank_dynamic)
    3132             :                              ? dst_dim::ArgN4 == src.dimension_4()
    3133             :                              : true) &&
    3134             :                         ((6 > DstTraits::dimension::rank_dynamic &&
    3135             :                           6 <= SrcTraits::dimension::rank_dynamic)
    3136             :                              ? dst_dim::ArgN5 == src.dimension_5()
    3137             :                              : true) &&
    3138             :                         ((7 > DstTraits::dimension::rank_dynamic &&
    3139             :                           7 <= SrcTraits::dimension::rank_dynamic)
    3140             :                              ? dst_dim::ArgN6 == src.dimension_6()
    3141             :                              : true) &&
    3142             :                         ((8 > DstTraits::dimension::rank_dynamic &&
    3143             :                           8 <= SrcTraits::dimension::rank_dynamic)
    3144             :                              ? dst_dim::ArgN7 == src.dimension_7()
    3145             :                              : true);
    3146             :       if (!assignable)
    3147             :         Kokkos::abort(
    3148             :             "View Assignment: trying to assign runtime dimension to non "
    3149             :             "matching compile time dimension.");
    3150             :     }
    3151             :     dst.m_impl_offset = dst_offset_type(src.m_impl_offset);
    3152             :     dst.m_impl_handle = Kokkos::Impl::ViewDataHandle<DstTraits>::assign(
    3153             :         src.m_impl_handle, src_track);
    3154             :   }
    3155             : };
    3156             : 
    3157             : //----------------------------------------------------------------------------
    3158             : //----------------------------------------------------------------------------
    3159             : // Subview mapping.
    3160             : // Deduce destination view type from source view traits and subview arguments
    3161             : 
    3162             : template <class, class ValueType, class Exts, class... Args>
    3163             : struct SubViewDataTypeImpl;
    3164             : 
    3165             : /* base case */
    3166             : template <class ValueType>
    3167             : struct SubViewDataTypeImpl<void, ValueType, Kokkos::Experimental::Extents<>> {
    3168             :   using type = ValueType;
    3169             : };
    3170             : 
    3171             : /* for integral args, subview doesn't have that dimension */
    3172             : template <class ValueType, size_t Ext, size_t... Exts, class Integral,
    3173             :           class... Args>
    3174             : struct SubViewDataTypeImpl<
    3175             :     std::enable_if_t<std::is_integral_v<std::decay_t<Integral>>>, ValueType,
    3176             :     Kokkos::Experimental::Extents<Ext, Exts...>, Integral, Args...>
    3177             :     : SubViewDataTypeImpl<void, ValueType,
    3178             :                           Kokkos::Experimental::Extents<Exts...>, Args...> {};
    3179             : 
    3180             : /* for ALL slice, subview has the same dimension */
    3181             : template <class ValueType, size_t Ext, size_t... Exts, class... Args>
    3182             : struct SubViewDataTypeImpl<void, ValueType,
    3183             :                            Kokkos::Experimental::Extents<Ext, Exts...>,
    3184             :                            Kokkos::ALL_t, Args...>
    3185             :     : SubViewDataTypeImpl<void, typename ApplyExtent<ValueType, Ext>::type,
    3186             :                           Kokkos::Experimental::Extents<Exts...>, Args...> {};
    3187             : 
    3188             : /* for pair-style slice, subview has dynamic dimension, since pair doesn't give
    3189             :  * static sizes */
    3190             : /* Since we don't allow interleaving of dynamic and static extents, make all of
    3191             :  * the dimensions to the left dynamic  */
    3192             : template <class ValueType, size_t Ext, size_t... Exts, class PairLike,
    3193             :           class... Args>
    3194             : struct SubViewDataTypeImpl<
    3195             :     std::enable_if_t<is_pair_like<PairLike>::value>, ValueType,
    3196             :     Kokkos::Experimental::Extents<Ext, Exts...>, PairLike, Args...>
    3197             :     : SubViewDataTypeImpl<
    3198             :           void, typename make_all_extents_into_pointers<ValueType>::type*,
    3199             :           Kokkos::Experimental::Extents<Exts...>, Args...> {};
    3200             : 
    3201             : template <class ValueType, class Exts, class... Args>
    3202             : struct SubViewDataType : SubViewDataTypeImpl<void, ValueType, Exts, Args...> {};
    3203             : 
    3204             : //----------------------------------------------------------------------------
    3205             : 
    3206             : template <class SrcTraits, class... Args>
    3207             : class ViewMapping<
    3208             :     std::enable_if_t<(
    3209             :         std::is_void_v<typename SrcTraits::specialize> &&
    3210             :         (std::is_same_v<typename SrcTraits::array_layout, Kokkos::LayoutLeft> ||
    3211             :          std::is_same_v<typename SrcTraits::array_layout,
    3212             :                         Kokkos::LayoutRight> ||
    3213             :          std::is_same_v<typename SrcTraits::array_layout,
    3214             :                         Kokkos::LayoutStride>))>,
    3215             :     SrcTraits, Args...> {
    3216             :  private:
    3217             :   static_assert(SrcTraits::rank == sizeof...(Args),
    3218             :                 "Subview mapping requires one argument for each dimension of "
    3219             :                 "source View");
    3220             : 
    3221             :   enum {
    3222             :     RZ = false,
    3223             :     R0 = bool(is_integral_extent<0, Args...>::value),
    3224             :     R1 = bool(is_integral_extent<1, Args...>::value),
    3225             :     R2 = bool(is_integral_extent<2, Args...>::value),
    3226             :     R3 = bool(is_integral_extent<3, Args...>::value),
    3227             :     R4 = bool(is_integral_extent<4, Args...>::value),
    3228             :     R5 = bool(is_integral_extent<5, Args...>::value),
    3229             :     R6 = bool(is_integral_extent<6, Args...>::value),
    3230             :     R7 = bool(is_integral_extent<7, Args...>::value)
    3231             :   };
    3232             : 
    3233             :   enum {
    3234             :     rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3) +
    3235             :            unsigned(R4) + unsigned(R5) + unsigned(R6) + unsigned(R7)
    3236             :   };
    3237             : 
    3238             :   // Whether right-most rank is a range.
    3239             :   enum {
    3240             :     R0_rev =
    3241             :         (0 == SrcTraits::rank
    3242             :              ? RZ
    3243             :              : (1 == SrcTraits::rank
    3244             :                     ? R0
    3245             :                     : (2 == SrcTraits::rank
    3246             :                            ? R1
    3247             :                            : (3 == SrcTraits::rank
    3248             :                                   ? R2
    3249             :                                   : (4 == SrcTraits::rank
    3250             :                                          ? R3
    3251             :                                          : (5 == SrcTraits::rank
    3252             :                                                 ? R4
    3253             :                                                 : (6 == SrcTraits::rank
    3254             :                                                        ? R5
    3255             :                                                        : (7 == SrcTraits::rank
    3256             :                                                               ? R6
    3257             :                                                               : R7))))))))
    3258             :   };
    3259             : 
    3260             :   // Subview's layout
    3261             :   using array_layout = std::conditional_t<
    3262             :       (            /* Same array layout IF */
    3263             :        (rank == 0) /* output rank zero */
    3264             :        || SubviewLegalArgsCompileTime<typename SrcTraits::array_layout,
    3265             :                                       typename SrcTraits::array_layout, rank,
    3266             :                                       SrcTraits::rank, 0, Args...>::value ||
    3267             :        // OutputRank 1 or 2, InputLayout Left, Interval 0
    3268             :        // because single stride one or second index has a stride.
    3269             :        (rank <= 2 && R0 &&
    3270             :         std::is_same_v<typename SrcTraits::array_layout,
    3271             :                        Kokkos::LayoutLeft>)  // replace with input rank
    3272             :        ||
    3273             :        // OutputRank 1 or 2, InputLayout Right, Interval [InputRank-1]
    3274             :        // because single stride one or second index has a stride.
    3275             :        (rank <= 2 && R0_rev &&
    3276             :         std::is_same_v<typename SrcTraits::array_layout,
    3277             :                        Kokkos::LayoutRight>)  // replace input rank
    3278             :        ),
    3279             :       typename SrcTraits::array_layout, Kokkos::LayoutStride>;
    3280             : 
    3281             :   using value_type = typename SrcTraits::value_type;
    3282             : 
    3283             :   using data_type =
    3284             :       typename SubViewDataType<value_type,
    3285             :                                typename Kokkos::Impl::ParseViewExtents<
    3286             :                                    typename SrcTraits::data_type>::type,
    3287             :                                Args...>::type;
    3288             : 
    3289             :  public:
    3290             :   using traits_type = Kokkos::ViewTraits<data_type, array_layout,
    3291             :                                          typename SrcTraits::device_type,
    3292             :                                          typename SrcTraits::memory_traits>;
    3293             : 
    3294             :   using type =
    3295             :       Kokkos::View<data_type, array_layout, typename SrcTraits::device_type,
    3296             :                    typename SrcTraits::memory_traits>;
    3297             : 
    3298             :   template <class MemoryTraits>
    3299             :   struct apply {
    3300             :     static_assert(Kokkos::is_memory_traits<MemoryTraits>::value);
    3301             : 
    3302             :     using traits_type =
    3303             :         Kokkos::ViewTraits<data_type, array_layout,
    3304             :                            typename SrcTraits::device_type, MemoryTraits>;
    3305             : 
    3306             :     using type = Kokkos::View<data_type, array_layout,
    3307             :                               typename SrcTraits::device_type, MemoryTraits>;
    3308             :   };
    3309             : 
    3310             :   // The presumed type is 'ViewMapping< traits_type , void >'
    3311             :   // However, a compatible ViewMapping is acceptable.
    3312             :   template <class DstTraits>
    3313             :   KOKKOS_INLINE_FUNCTION static void assign(
    3314             :       ViewMapping<DstTraits, void>& dst,
    3315             :       ViewMapping<SrcTraits, void> const& src, Args... args) {
    3316             :     static_assert(ViewMapping<DstTraits, traits_type, void>::is_assignable,
    3317             :                   "Subview destination type must be compatible with subview "
    3318             :                   "derived type");
    3319             : 
    3320             :     using DstType = ViewMapping<DstTraits, void>;
    3321             : 
    3322             :     using dst_offset_type = typename DstType::offset_type;
    3323             : 
    3324             :     const SubviewExtents<SrcTraits::rank, rank> extents(src.m_impl_offset.m_dim,
    3325             :                                                         args...);
    3326             : 
    3327             :     dst.m_impl_offset = dst_offset_type(src.m_impl_offset, extents);
    3328             : 
    3329             :     dst.m_impl_handle = ViewDataHandle<DstTraits>::assign(
    3330             :         src.m_impl_handle,
    3331             :         src.m_impl_offset(extents.domain_offset(0), extents.domain_offset(1),
    3332             :                           extents.domain_offset(2), extents.domain_offset(3),
    3333             :                           extents.domain_offset(4), extents.domain_offset(5),
    3334             :                           extents.domain_offset(6), extents.domain_offset(7)));
    3335             :   }
    3336             : };
    3337             : 
    3338             : //----------------------------------------------------------------------------
    3339             : 
    3340             : }  // namespace Impl
    3341             : }  // namespace Kokkos
    3342             : 
    3343             : //----------------------------------------------------------------------------
    3344             : //----------------------------------------------------------------------------
    3345             : 
    3346             : namespace Kokkos {
    3347             : namespace Impl {
    3348             : 
    3349             : template <class Map, class... Indices, std::size_t... Enumerate>
    3350    73224123 : KOKKOS_FUNCTION bool within_range(Map const& map,
    3351             :                                   std::index_sequence<Enumerate...>,
    3352             :                                   Indices... indices) {
    3353    73224123 :   return (((std::size_t)indices < map.extent(Enumerate)) && ...);
    3354             : }
    3355             : 
    3356             : // Disabled when using MDSpan because the MDSpan implementation has its own
    3357             : // version
    3358             : #ifndef KOKKOS_ENABLE_IMPL_MDSPAN
    3359             : template <class... Indices>
    3360             : KOKKOS_FUNCTION constexpr char* append_formatted_multidimensional_index(
    3361             :     char* dest, Indices... indices) {
    3362             :   char* d = dest;
    3363             :   strcat(d, "[");
    3364             :   (
    3365             :       [&] {
    3366             :         d += strlen(d);
    3367             :         to_chars_i(d,
    3368             :                    d + 20,  // 20 digits ought to be enough
    3369             :                    indices);
    3370             :         strcat(d, ",");
    3371             :       }(),
    3372             :       ...);
    3373             :   d[strlen(d) - 1] = ']';  // overwrite trailing comma
    3374             :   return dest;
    3375             : }
    3376             : #endif
    3377             : 
    3378             : template <class Map, class... Indices, std::size_t... Enumerate>
    3379           0 : KOKKOS_FUNCTION void print_extents(char* dest, Map const& map,
    3380             :                                    std::index_sequence<Enumerate...>) {
    3381           0 :   append_formatted_multidimensional_index(dest, map.extent(Enumerate)...);
    3382           0 : }
    3383             : 
    3384             : template <class T>
    3385             : using printable_label_typedef_t = typename T::printable_label_typedef;
    3386             : 
    3387             : template <class MemorySpace, class ViewType, class MapType, class... Args>
    3388    39447979 : KOKKOS_INLINE_FUNCTION void view_verify_operator_bounds(
    3389             :     Kokkos::Impl::ViewTracker<ViewType> const& tracker, const MapType& map,
    3390             :     Args... args) {
    3391    39447979 :   if (!within_range(map, std::make_index_sequence<sizeof...(Args)>(),
    3392             :                     args...)) {
    3393           0 :     char err[256] = "";
    3394           0 :     strcat(err, "Kokkos::View ERROR: out of bounds access");
    3395           0 :     strcat(err, " label=(\"");
    3396           0 :     KOKKOS_IF_ON_HOST(
    3397             :         if (tracker.m_tracker.has_record()) {
    3398             :           strncat(err, tracker.m_tracker.template get_label<void>().c_str(),
    3399             :                   128);
    3400             :         } else { strcat(err, "**UNMANAGED**"); })
    3401             :     KOKKOS_IF_ON_DEVICE([&] {
    3402             :       // Check #1: is there a SharedAllocationRecord?  (we won't use it, but
    3403             :       // if its not there then there isn't a corresponding
    3404             :       // SharedAllocationHeader containing a label).  This check should cover
    3405             :       // the case of Views that don't have the Unmanaged trait but were
    3406             :       // initialized by pointer.
    3407             :       if (!tracker.m_tracker.has_record()) {
    3408             :         strcat(err, "**UNMANAGED**");
    3409             :         return;
    3410             :       }
    3411             :       // Check #2: does the ViewMapping have the printable_label_typedef
    3412             :       // defined? See above that only the non-specialized standard-layout
    3413             :       // ViewMapping has this defined by default. The existence of this
    3414             :       // alias indicates the existence of MapType::is_managed
    3415             :       if constexpr (is_detected_v<printable_label_typedef_t, MapType>) {
    3416             :         // Check #3: is the View managed as determined by the MemoryTraits?
    3417             :         if constexpr (MapType::is_managed != 0) {
    3418             :           SharedAllocationHeader const* const header =
    3419             :               SharedAllocationHeader::get_header(
    3420             :                   static_cast<void const*>(map.data()));
    3421             :           char const* const label = header->label();
    3422             :           strcat(err, label);
    3423             :           return;
    3424             :         }
    3425             :         strcat(err, "**UNAVAILABLE**");
    3426             :       }
    3427             :     }();)
    3428           0 :     strcat(err, "\") with indices ");
    3429           0 :     append_formatted_multidimensional_index(err, args...);
    3430           0 :     strcat(err, " but extents ");
    3431           0 :     print_extents(err, map, std::make_index_sequence<sizeof...(Args)>());
    3432             :     Kokkos::abort(err);
    3433             :   }
    3434    39447979 : }
    3435             : 
    3436             : // primary template: memory space is accessible, do nothing.
    3437             : template <class MemorySpace, class AccessSpace,
    3438             :           bool = SpaceAccessibility<AccessSpace, MemorySpace>::accessible>
    3439             : struct RuntimeCheckViewMemoryAccessViolation {
    3440             :   template <class Track, class Map>
    3441    38778703 :   KOKKOS_FUNCTION RuntimeCheckViewMemoryAccessViolation(char const* const,
    3442             :                                                         Track const&,
    3443             :                                                         Map const&) {}
    3444             : };
    3445             : 
    3446             : // explicit specialization: memory access violation will occur, call abort with
    3447             : // the specified error message.
    3448             : template <class MemorySpace, class AccessSpace>
    3449             : struct RuntimeCheckViewMemoryAccessViolation<MemorySpace, AccessSpace, false> {
    3450             :   template <class Track, class Map>
    3451             :   KOKKOS_FUNCTION RuntimeCheckViewMemoryAccessViolation(char const* const msg,
    3452             :                                                         Track const& track,
    3453             :                                                         Map const&) {
    3454             :     char err[256] = "";
    3455             :     strncat(err, msg, 64);
    3456             :     strcat(err, " (label=\"");
    3457             : 
    3458             :     KOKKOS_IF_ON_HOST(({
    3459             :       auto const tracker = track.m_tracker;
    3460             : 
    3461             :       if (tracker.has_record()) {
    3462             :         strncat(err, tracker.template get_label<void>().c_str(), 128);
    3463             :       } else {
    3464             :         strcat(err, "**UNMANAGED**");
    3465             :       }
    3466             :     }))
    3467             : 
    3468             :     KOKKOS_IF_ON_DEVICE(({
    3469             :       strcat(err, "**UNAVAILABLE**");
    3470             :       (void)track;
    3471             :     }))
    3472             : 
    3473             :     strcat(err, "\")");
    3474             : 
    3475             :     Kokkos::abort(err);
    3476             :   }
    3477             : };
    3478             : 
    3479             : template <class MemorySpace, class Track, class Map, class... Ignore>
    3480    38778703 : KOKKOS_FUNCTION void runtime_check_memory_access_violation(
    3481             :     char const* const msg, Track const& track, Map const& map, Ignore...) {
    3482    38778703 :   KOKKOS_IF_ON_HOST(
    3483             :       ((void)RuntimeCheckViewMemoryAccessViolation<MemorySpace,
    3484             :                                                    DefaultHostExecutionSpace>(
    3485             :            msg, track, map);))
    3486             :   KOKKOS_IF_ON_DEVICE(
    3487             :       ((void)RuntimeCheckViewMemoryAccessViolation<MemorySpace,
    3488             :                                                    DefaultExecutionSpace>(
    3489             :            msg, track, map);))
    3490    38778703 : }
    3491             : 
    3492             : } /* namespace Impl */
    3493             : } /* namespace Kokkos */
    3494             : 
    3495             : //----------------------------------------------------------------------------
    3496             : //----------------------------------------------------------------------------
    3497             : 
    3498             : #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_MAPPING_HPP */

Generated by: LCOV version 1.14