text: /*
  //@HEADER
  // ************************************************************************
  //
  //                        Kokkos v. 2.0
  //              Copyright (2014) Sandia Corporation
  //
  // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  // the U.S. Government retains certain rights in this software.
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  // 1. Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  //
  // 2. Redistributions in binary form must reproduce the above copyright
  // notice, this list of conditions and the following disclaimer in the
  // documentation and/or other materials provided with the distribution.
  //
  // 3. Neither the name of the Corporation nor the names of the
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
  // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  //
  // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
  //
  // ************************************************************************
  //@HEADER
  */
  
  /// \file Kokkos_DynRankView.hpp
  /// \brief Declaration and definition of Kokkos::Experimental::DynRankView.
  ///
  /// This header file declares and defines Kokkos::Experimental::DynRankView and its
  /// related nonmember functions.
  
  #ifndef KOKKOS_DYNRANKVIEW_HPP
  #define KOKKOS_DYNRANKVIEW_HPP
  
  #include <Kokkos_Core.hpp>
  #include <impl/Kokkos_Error.hpp>
  #include <type_traits>
  
  namespace Kokkos {
  namespace Experimental {
  
  template< typename DataType , class ... Properties >
  class DynRankView;  //forward declare
  
  namespace Impl {
  
  template <typename Specialize>
  struct DynRankDimTraits {
  
    enum : size_t{unspecified = ~size_t(0)};
  
    // Compute the rank of the view from the nonzero dimension arguments.
    KOKKOS_INLINE_FUNCTION
    static size_t computeRank( const size_t N0
                             , const size_t N1
                             , const size_t N2
                             , const size_t N3
                             , const size_t N4
                             , const size_t N5
                             , const size_t N6
                             , const size_t N7 )
    {
      return
        (   (N6 == unspecified && N5 == unspecified && N4 == unspecified && N3 == unspecified && N2 == unspecified && N1 == unspecified && N0 == unspecified) ? 0
        : ( (N6 == unspecified && N5 == unspecified && N4 == unspecified && N3 == unspecified && N2 == unspecified && N1 == unspecified) ? 1
        : ( (N6 == unspecified && N5 == unspecified && N4 == unspecified && N3 == unspecified && N2 == unspecified) ? 2
        : ( (N6 == unspecified && N5 == unspecified && N4 == unspecified && N3 == unspecified) ? 3
        : ( (N6 == unspecified && N5 == unspecified && N4 == unspecified) ? 4
        : ( (N6 == unspecified && N5 == unspecified) ? 5
        : ( (N6 == unspecified) ? 6
        : 7 ) ) ) ) ) ) );
    }
  
    // Compute the rank of the view from the nonzero layout arguments.
    template <typename Layout>
    KOKKOS_INLINE_FUNCTION
    static size_t computeRank( const Layout& layout )
    {
      return computeRank( layout.dimension[0]
                        , layout.dimension[1]
                        , layout.dimension[2]
                        , layout.dimension[3]
                        , layout.dimension[4]
                        , layout.dimension[5]
                        , layout.dimension[6]
                        , layout.dimension[7] );
    }
  
    // Extra overload to match that for specialize types v2
    template <typename Layout, typename ... P>
    KOKKOS_INLINE_FUNCTION
    static size_t computeRank( const Kokkos::Impl::ViewCtorProp<P...>& prop, const Layout& layout )
    {
      return computeRank(layout);
    }
  
    // Create the layout for the rank-7 view.
    // Non-strided Layout
    template <typename Layout>
    KOKKOS_INLINE_FUNCTION
    static typename std::enable_if< (std::is_same<Layout , Kokkos::LayoutRight>::value || std::is_same<Layout , Kokkos::LayoutLeft>::value) , Layout >::type createLayout( const Layout& layout )
    {
      return Layout( layout.dimension[0] != unspecified ? layout.dimension[0] : 1
                   , layout.dimension[1] != unspecified ? layout.dimension[1] : 1
                   , layout.dimension[2] != unspecified ? layout.dimension[2] : 1
                   , layout.dimension[3] != unspecified ? layout.dimension[3] : 1
                   , layout.dimension[4] != unspecified ? layout.dimension[4] : 1
                   , layout.dimension[5] != unspecified ? layout.dimension[5] : 1
                   , layout.dimension[6] != unspecified ? layout.dimension[6] : 1
                   , layout.dimension[7] != unspecified ? layout.dimension[7] : 1
                   );
    }
  
    // LayoutStride
    template <typename Layout>
    KOKKOS_INLINE_FUNCTION
    static typename std::enable_if< (std::is_same<Layout , Kokkos::LayoutStride>::value) , Layout>::type createLayout( const Layout& layout )
    {
      return Layout( layout.dimension[0] != unspecified ? layout.dimension[0] : 1
                   , layout.stride[0]
                   , layout.dimension[1] != unspecified ? layout.dimension[1] : 1
                   , layout.stride[1]
                   , layout.dimension[2] != unspecified ? layout.dimension[2] : 1
                   , layout.stride[2]
                   , layout.dimension[3] != unspecified ? layout.dimension[3] : 1
                   , layout.stride[3]
                   , layout.dimension[4] != unspecified ? layout.dimension[4] : 1
                   , layout.stride[4]
                   , layout.dimension[5] != unspecified ? layout.dimension[5] : 1
                   , layout.stride[5]
                   , layout.dimension[6] != unspecified ? layout.dimension[6] : 1
                   , layout.stride[6]
                   , layout.dimension[7] != unspecified ? layout.dimension[7] : 1
                   , layout.stride[7]
                   );
    }
  
    // Extra overload to match that for specialize types
    template <typename Traits, typename ... P>
    KOKKOS_INLINE_FUNCTION
    static typename std::enable_if< (std::is_same<typename Traits::array_layout , Kokkos::LayoutRight>::value || std::is_same<typename Traits::array_layout , Kokkos::LayoutLeft>::value || std::is_same<typename Traits::array_layout , Kokkos::LayoutStride>::value) , typename Traits::array_layout >::type createLayout( const ViewCtorProp<P...>& prop, const typename Traits::array_layout& layout )
    {
      return createLayout( layout );
    }
  
    // Create a view from the given dimension arguments.
    // This is only necessary because the shmem constructor doesn't take a layout.
    //   NDE shmem View's are not compatible with the added view_alloc value_type / fad_dim deduction functionality
    template <typename ViewType, typename ViewArg>
    static ViewType createView( const ViewArg& arg
                              , const size_t N0
                              , const size_t N1
                              , const size_t N2
                              , const size_t N3
                              , const size_t N4
                              , const size_t N5
                              , const size_t N6
                              , const size_t N7 )
    {
      return ViewType( arg
                     , N0 != unspecified ? N0 : 1
                     , N1 != unspecified ? N1 : 1
                     , N2 != unspecified ? N2 : 1
                     , N3 != unspecified ? N3 : 1
                     , N4 != unspecified ? N4 : 1
                     , N5 != unspecified ? N5 : 1
                     , N6 != unspecified ? N6 : 1
                     , N7 != unspecified ? N7 : 1 );
    }
  };
  
    // Non-strided Layout
    template <typename Layout , typename iType>
    KOKKOS_INLINE_FUNCTION
    static typename std::enable_if< (std::is_same<Layout , Kokkos::LayoutRight>::value || std::is_same<Layout , Kokkos::LayoutLeft>::value) && std::is_integral<iType>::value , Layout >::type
    reconstructLayout( const Layout& layout , iType dynrank )
    {
      return Layout( dynrank > 0 ? layout.dimension[0] : ~size_t(0)
                   , dynrank > 1 ? layout.dimension[1] : ~size_t(0)
                   , dynrank > 2 ? layout.dimension[2] : ~size_t(0)
                   , dynrank > 3 ? layout.dimension[3] : ~size_t(0)
                   , dynrank > 4 ? layout.dimension[4] : ~size_t(0)
                   , dynrank > 5 ? layout.dimension[5] : ~size_t(0)
                   , dynrank > 6 ? layout.dimension[6] : ~size_t(0)
                   , dynrank > 7 ? layout.dimension[7] : ~size_t(0)
                   );
    }
  
    // LayoutStride
    template <typename Layout , typename iType>
    KOKKOS_INLINE_FUNCTION
    static typename std::enable_if< (std::is_same<Layout , Kokkos::LayoutStride>::value) && std::is_integral<iType>::value , Layout >::type
    reconstructLayout( const Layout& layout , iType dynrank )
    {
      return Layout( dynrank > 0 ? layout.dimension[0] : ~size_t(0)
                   , dynrank > 0 ? layout.stride[0] : (0)
                   , dynrank > 1 ? layout.dimension[1] : ~size_t(0)
                   , dynrank > 1 ? layout.stride[1] : (0)
                   , dynrank > 2 ? layout.dimension[2] : ~size_t(0)
                   , dynrank > 2 ? layout.stride[2] : (0)
                   , dynrank > 3 ? layout.dimension[3] : ~size_t(0)
                   , dynrank > 3 ? layout.stride[3] : (0)
                   , dynrank > 4 ? layout.dimension[4] : ~size_t(0)
                   , dynrank > 4 ? layout.stride[4] : (0)
                   , dynrank > 5 ? layout.dimension[5] : ~size_t(0)
                   , dynrank > 5 ? layout.stride[5] : (0)
                   , dynrank > 6 ? layout.dimension[6] : ~size_t(0)
                   , dynrank > 6 ? layout.stride[6] : (0)
                   , dynrank > 7 ? layout.dimension[7] : ~size_t(0)
                   , dynrank > 7 ? layout.stride[7] : (0)
                   );
    }
  
  
  /** \brief  Debug bounds-checking routines */
  // Enhanced debug checking - most infrastructure matches that of functions in
  // Kokkos_ViewMapping; additional checks for extra arguments beyond rank are 0
  template< unsigned ,  typename iType0 , class MapType >
  KOKKOS_INLINE_FUNCTION
  bool dyn_rank_view_verify_operator_bounds( const iType0 & , const MapType & )
  { return true ; }
  
  template< unsigned R , typename iType0 ,  class MapType , typename iType1 , class ... Args >
  KOKKOS_INLINE_FUNCTION
  bool dyn_rank_view_verify_operator_bounds
    ( const iType0  & rank
    , const MapType & map
    , const iType1  & i
    , Args ... args
    )
  {
    if ( static_cast<iType0>(R) < rank ) {
      return ( size_t(i) < map.extent(R) )
         && dyn_rank_view_verify_operator_bounds<R+1>( rank , map , args ... );
    }
    else if ( i != 0 ) {
      printf("DynRankView Debug Bounds Checking Error: at rank %u\n  Extra arguments beyond the rank must be zero \n",R);
      return ( false )
         && dyn_rank_view_verify_operator_bounds<R+1>( rank , map , args ... );
    }
    else {
      return ( true )
         && dyn_rank_view_verify_operator_bounds<R+1>( rank , map , args ... );
    }
  }
  
  template< unsigned , class MapType >
  inline
  void dyn_rank_view_error_operator_bounds( char * , int , const MapType & )
  {}
  
  template< unsigned R , class MapType , class iType , class ... Args >
  inline
  void dyn_rank_view_error_operator_bounds
    ( char * buf
    , int len
    , const MapType & map
    , const iType   & i
    , Args ... args
    )
  {
    const int n =
      snprintf(buf,len," %ld < %ld %c"
              , static_cast<unsigned long>(i)
              , static_cast<unsigned long>( map.extent(R) )
              , ( sizeof...(Args) ? ',' : ')' )
              );
    dyn_rank_view_error_operator_bounds<R+1>(buf+n,len-n,map,args...);
  }
  
  // op_rank = rank of the operator version that was called
  template< typename MemorySpace
          , typename iType0 , typename iType1 ,  class MapType , class ... Args >
  KOKKOS_INLINE_FUNCTION
  void dyn_rank_view_verify_operator_bounds
    ( const iType0 & op_rank , const iType1 & rank
    , const Kokkos::Impl::SharedAllocationTracker & tracker
    , const MapType & map , Args ... args )
  {
    if ( static_cast<iType0>(rank) > op_rank ) {
      Kokkos::abort( "DynRankView Bounds Checking Error: Need at least rank arguments to the operator()" );
    }
  
    if ( ! dyn_rank_view_verify_operator_bounds<0>( rank , map , args ... ) ) {
  #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
      enum { LEN = 1024 };
      char buffer[ LEN ];
      const std::string label = tracker.template get_label<MemorySpace>();
      int n = snprintf(buffer,LEN,"DynRankView bounds error of view %s (", label.c_str());
      dyn_rank_view_error_operator_bounds<0>( buffer + n , LEN - n , map , args ... );
      Kokkos::Impl::throw_runtime_exception(std::string(buffer));
  #else
      Kokkos::abort("DynRankView bounds error");
  #endif
    }
  }
  
  
  /** \brief  Assign compatible default mappings */
  struct ViewToDynRankViewTag {};
  
  } // namespace Impl
  } // namespace Experimental
  
  namespace Impl {
  
  template< class DstTraits , class SrcTraits >
  class ViewMapping< DstTraits , SrcTraits ,
    typename std::enable_if<(
      std::is_same< typename DstTraits::memory_space , typename SrcTraits::memory_space >::value
      &&
      std::is_same< typename DstTraits::specialize , void >::value
      &&
      std::is_same< typename SrcTraits::specialize , void >::value
      &&
      (
        std::is_same< typename DstTraits::array_layout , typename SrcTraits::array_layout >::value
        ||
        (
          (
            std::is_same< typename DstTraits::array_layout , Kokkos::LayoutLeft >::value ||
            std::is_same< typename DstTraits::array_layout , Kokkos::LayoutRight >::value ||
            std::is_same< typename DstTraits::array_layout , Kokkos::LayoutStride >::value
          )
          &&
          (
            std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutLeft >::value ||
            std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutRight >::value ||
            std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutStride >::value
          )
        )
      )
    ) , Kokkos::Experimental::Impl::ViewToDynRankViewTag >::type >
  {
  private:
  
    enum { is_assignable_value_type =
      std::is_same< typename DstTraits::value_type
                  , typename SrcTraits::value_type >::value ||
      std::is_same< typename DstTraits::value_type
                  , typename SrcTraits::const_value_type >::value };
  
    enum { is_assignable_layout =
      std::is_same< typename DstTraits::array_layout
                  , typename SrcTraits::array_layout >::value ||
      std::is_same< typename DstTraits::array_layout
                  , Kokkos::LayoutStride >::value
      };
  
  public:
  
    enum { is_assignable = is_assignable_value_type &&
                           is_assignable_layout };
  
    typedef ViewMapping< DstTraits , void >  DstType ;
    typedef ViewMapping< SrcTraits , void >  SrcType ;
  
    template < typename DT , typename ... DP , typename ST , typename ... SP >
    KOKKOS_INLINE_FUNCTION
    static void assign( Kokkos::Experimental::DynRankView< DT , DP...> & dst ,  const Kokkos::View< ST , SP... > & src )
      {
        static_assert( is_assignable_value_type
                     , "View assignment must have same value type or const = non-const" );
  
        static_assert( is_assignable_layout
                     , "View assignment must have compatible layout or have rank <= 1" );
  
      // Removed dimension checks...
  
        typedef typename DstType::offset_type  dst_offset_type ;
        dst.m_map.m_offset = dst_offset_type(std::integral_constant<unsigned,0>() , src.layout() ); //Check this for integer input1 for padding, etc
        dst.m_map.m_handle = Kokkos::Impl::ViewDataHandle< DstTraits >::assign( src.m_map.m_handle , src.m_track );
        dst.m_track.assign( src.m_track , DstTraits::is_managed );
        dst.m_rank = src.Rank ;
      }
  };
  
  } //end Impl
  
  namespace Experimental {
  
  /* \class DynRankView
   * \brief Container that creates a Kokkos view with rank determined at runtime.
   *   Essentially this is a rank 7 view
   *
   *   Changes from View
   *   1. The rank of the DynRankView is returned by the method rank()
   *   2. Max rank of a DynRankView is 7
   *   3. subview called with 'subview(...)' or 'subdynrankview(...)' (backward compatibility) 
   *   4. Every subview is returned with LayoutStride
   *   5. Copy and Copy-Assign View to DynRankView
   *   6. deep_copy between Views and DynRankViews
   *   7. rank( view ); returns the rank of View or DynRankView
   *
   */
  
  template< class > struct is_dyn_rank_view : public std::false_type {};
  
  template< class D, class ... P >
  struct is_dyn_rank_view< Kokkos::Experimental::DynRankView<D,P...> > : public std::true_type {};
  
  
  template< typename DataType , class ... Properties >
  class DynRankView : public ViewTraits< DataType , Properties ... >
  {
    static_assert( !std::is_array<DataType>::value && !std::is_pointer<DataType>::value , "Cannot template DynRankView with array or pointer datatype - must be pod" );
  
  private:
    template < class , class ... > friend class DynRankView ;
    template < class , class ... > friend class Impl::ViewMapping ;
  
  public:
    typedef ViewTraits< DataType , Properties ... > drvtraits ;
  
    typedef View< DataType******* , Properties...> view_type ;
  
    typedef ViewTraits< DataType******* , Properties ... > traits ;
  
  
  private:
    typedef Kokkos::Impl::ViewMapping< traits , void > map_type ;
    typedef Kokkos::Experimental::Impl::SharedAllocationTracker      track_type ;
  
    track_type  m_track ;
    map_type    m_map ;
    unsigned m_rank;
  
  public:
    KOKKOS_INLINE_FUNCTION
    view_type & DownCast() const { return ( view_type & ) (*this); }
    KOKKOS_INLINE_FUNCTION
    const view_type & ConstDownCast() const { return (const view_type & ) (*this); }
  
    //Types below - at least the HostMirror requires the value_type, NOT the rank 7 data_type of the traits
  
    /** \brief  Compatible view of array of scalar types */
    typedef DynRankView< typename drvtraits::scalar_array_type ,
                  typename drvtraits::array_layout ,
                  typename drvtraits::device_type ,
                  typename drvtraits::memory_traits >
      array_type ;
  
    /** \brief  Compatible view of const data type */
    typedef DynRankView< typename drvtraits::const_data_type ,
                  typename drvtraits::array_layout ,
                  typename drvtraits::device_type ,
                  typename drvtraits::memory_traits >
      const_type ;
  
    /** \brief  Compatible view of non-const data type */
    typedef DynRankView< typename drvtraits::non_const_data_type ,
                  typename drvtraits::array_layout ,
                  typename drvtraits::device_type ,
                  typename drvtraits::memory_traits >
      non_const_type ;
  
    /** \brief  Compatible HostMirror view */
    typedef DynRankView< typename drvtraits::non_const_data_type ,
                  typename drvtraits::array_layout ,
                  typename drvtraits::host_mirror_space >
      HostMirror ;
  
  
    //----------------------------------------
    // Domain rank and extents
  
  //  enum { Rank = map_type::Rank }; //Will be dyn rank of 7 always, keep the enum?
  
    template< typename iType >
    KOKKOS_INLINE_FUNCTION constexpr
    typename std::enable_if< std::is_integral<iType>::value , size_t >::type
    extent( const iType & r ) const
      { return m_map.extent(r); }
  
    template< typename iType >
    KOKKOS_INLINE_FUNCTION constexpr
    typename std::enable_if< std::is_integral<iType>::value , int >::type
    extent_int( const iType & r ) const
      { return static_cast<int>(m_map.extent(r)); }
  
    KOKKOS_INLINE_FUNCTION constexpr
    typename traits::array_layout layout() const
      { return m_map.layout(); }
  
    //----------------------------------------
    /*  Deprecate all 'dimension' functions in favor of
     *  ISO/C++ vocabulary 'extent'.
     */
  
    template< typename iType >
    KOKKOS_INLINE_FUNCTION constexpr
    typename std::enable_if< std::is_integral<iType>::value , size_t >::type
    dimension( const iType & r ) const { return extent( r ); }
  
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const { return m_map.dimension_0(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const { return m_map.dimension_1(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const { return m_map.dimension_2(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const { return m_map.dimension_3(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const { return m_map.dimension_4(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const { return m_map.dimension_5(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const { return m_map.dimension_6(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const { return m_map.dimension_7(); }
  
    //----------------------------------------
  
    KOKKOS_INLINE_FUNCTION constexpr size_t size() const { return m_map.dimension_0() *
                                                                  m_map.dimension_1() *
                                                                  m_map.dimension_2() *
                                                                  m_map.dimension_3() *
                                                                  m_map.dimension_4() *
                                                                  m_map.dimension_5() *
                                                                  m_map.dimension_6() *
                                                                  m_map.dimension_7(); }
  
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const { return m_map.stride_0(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const { return m_map.stride_1(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const { return m_map.stride_2(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const { return m_map.stride_3(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const { return m_map.stride_4(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const { return m_map.stride_5(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const { return m_map.stride_6(); }
    KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const { return m_map.stride_7(); }
  
    template< typename iType >
    KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const { m_map.stride(s); }
  
    //----------------------------------------
    // Range span is the span which contains all members.
  
    typedef typename map_type::reference_type  reference_type ;
    typedef typename map_type::pointer_type    pointer_type ;
  
    enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
  
    KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return m_map.span(); }
    // Deprecated, use 'span()' instead
    KOKKOS_INLINE_FUNCTION constexpr size_t capacity() const { return m_map.span(); }
    KOKKOS_INLINE_FUNCTION constexpr bool   span_is_contiguous() const { return m_map.span_is_contiguous(); }
    KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const { return m_map.data(); }
  
    // Deprecated, use 'span_is_contigous()' instead
    KOKKOS_INLINE_FUNCTION constexpr bool   is_contiguous() const { return m_map.span_is_contiguous(); }
    // Deprecated, use 'data()' instead
    KOKKOS_INLINE_FUNCTION constexpr pointer_type ptr_on_device() const { return m_map.data(); }
  
    //----------------------------------------
    // Allow specializations to query their specialized map
  
    KOKKOS_INLINE_FUNCTION
    const Kokkos::Impl::ViewMapping< traits , void > &
    implementation_map() const { return m_map ; }
  
    //----------------------------------------
  
  private:
  
    enum {
      is_layout_left = std::is_same< typename traits::array_layout
                                    , Kokkos::LayoutLeft >::value ,
  
      is_layout_right = std::is_same< typename traits::array_layout
                                    , Kokkos::LayoutRight >::value ,
  
      is_layout_stride = std::is_same< typename traits::array_layout
                                     , Kokkos::LayoutStride >::value ,
  
      is_default_map =
        std::is_same< typename traits::specialize , void >::value &&
        ( is_layout_left || is_layout_right || is_layout_stride )
    };
  
    template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible > struct verify_space
      { KOKKOS_FORCEINLINE_FUNCTION static void check() {} };
  
    template< class Space > struct verify_space<Space,false>
      { KOKKOS_FORCEINLINE_FUNCTION static void check()
          { Kokkos::abort("Kokkos::DynRankView ERROR: attempt to access inaccessible memory space"); };
      };
  
  // Bounds checking macros
  #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
  
  // rank of the calling operator - included as first argument in ARG
  #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( ARG ) \
    DynRankView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check(); \
    Kokkos::Experimental::Impl::dyn_rank_view_verify_operator_bounds< typename traits::memory_space > ARG ;
  
  #else
  
  #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( ARG ) \
    DynRankView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
  
  #endif
  
  public:
  
    KOKKOS_INLINE_FUNCTION
    constexpr unsigned rank() const { return m_rank; }
  
  
    //operators ()
    // Rank 0
    KOKKOS_INLINE_FUNCTION
    reference_type operator()() const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (0 , this->rank(), m_track, m_map) )
        return implementation_map().reference();
        //return m_map.reference(0,0,0,0,0,0,0);
      }
  
    // Rank 1
    // This assumes a contiguous underlying memory (i.e. no padding, no striding...)
    template< typename iType >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< std::is_same<typename drvtraits::value_type, typename drvtraits::scalar_array_type>::value && std::is_integral<iType>::value, reference_type>::type
    operator[](const iType & i0) const
      {
        //Phalanx is violating this, since they use the operator to access ALL elements in the allocation
        //KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (1 , this->rank(), m_track, m_map) )
        return data()[i0];
      }
  
    // This assumes a contiguous underlying memory (i.e. no padding, no striding...
    // AND a Trilinos/Sacado scalar type )
    template< typename iType >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !std::is_same<typename drvtraits::value_type, typename drvtraits::scalar_array_type>::value && std::is_integral<iType>::value, reference_type>::type
    operator[](const iType & i0) const
      {
  //      auto map = implementation_map();
        const size_t dim_scalar = m_map.dimension_scalar();
        const size_t bytes = this->span() / dim_scalar;
  
        typedef Kokkos::View<DataType*, typename traits::array_layout, typename traits::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged | traits::memory_traits::RandomAccess | traits::memory_traits::Atomic> > tmp_view_type;
        tmp_view_type rankone_view(this->data(), bytes, dim_scalar);
        return rankone_view(i0);
      }
  
    // Rank 1 parenthesis
    template< typename iType >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_same<typename traits::specialize , void>::value && std::is_integral<iType>::value), reference_type>::type
    operator()(const iType & i0 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (1 , this->rank(), m_track, m_map, i0) )
        return m_map.reference(i0);
      }
  
    template< typename iType >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !(std::is_same<typename traits::specialize , void>::value && std::is_integral<iType>::value), reference_type>::type
    operator()(const iType & i0 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (1 , this->rank(), m_track, m_map, i0) )
        return m_map.reference(i0,0,0,0,0,0,0);
      }
  
    // Rank 2
    template< typename iType0 , typename iType1 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_same<typename traits::specialize , void>::value && std::is_integral<iType0>::value  && std::is_integral<iType1>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (2 , this->rank(), m_track, m_map, i0, i1) )
        return m_map.reference(i0,i1);
      }
  
    template< typename iType0 , typename iType1 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !(std::is_same<typename drvtraits::specialize , void>::value && std::is_integral<iType0>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (2 , this->rank(), m_track, m_map, i0, i1) )
        return m_map.reference(i0,i1,0,0,0,0,0);
      }
  
    // Rank 3
    template< typename iType0 , typename iType1 , typename iType2 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_same<typename traits::specialize , void>::value && std::is_integral<iType0>::value  && std::is_integral<iType1>::value && std::is_integral<iType2>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (3 , this->rank(), m_track, m_map, i0, i1, i2) )
        return m_map.reference(i0,i1,i2);
      }
  
    template< typename iType0 , typename iType1 , typename iType2 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !(std::is_same<typename drvtraits::specialize , void>::value && std::is_integral<iType0>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (3 , this->rank(), m_track, m_map, i0, i1, i2) )
        return m_map.reference(i0,i1,i2,0,0,0,0);
      }
  
    // Rank 4
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_same<typename traits::specialize , void>::value && std::is_integral<iType0>::value  && std::is_integral<iType1>::value && std::is_integral<iType2>::value && std::is_integral<iType3>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (4 , this->rank(), m_track, m_map, i0, i1, i2, i3) )
        return m_map.reference(i0,i1,i2,i3);
      }
  
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !(std::is_same<typename drvtraits::specialize , void>::value && std::is_integral<iType0>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (4 , this->rank(), m_track, m_map, i0, i1, i2, i3) )
        return m_map.reference(i0,i1,i2,i3,0,0,0);
      }
  
    // Rank 5
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3, typename iType4 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_same<typename traits::specialize , void>::value && std::is_integral<iType0>::value  && std::is_integral<iType1>::value && std::is_integral<iType2>::value && std::is_integral<iType3>::value && std::is_integral<iType4>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 , const iType4 & i4 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (5 , this->rank(), m_track, m_map, i0, i1, i2, i3, i4) )
        return m_map.reference(i0,i1,i2,i3,i4);
      }
  
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3, typename iType4 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !(std::is_same<typename drvtraits::specialize , void>::value && std::is_integral<iType0>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 , const iType4 & i4 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (5 , this->rank(), m_track, m_map, i0, i1, i2, i3, i4) )
        return m_map.reference(i0,i1,i2,i3,i4,0,0);
      }
  
    // Rank 6
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3, typename iType4 , typename iType5 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_same<typename traits::specialize , void>::value && std::is_integral<iType0>::value  && std::is_integral<iType1>::value && std::is_integral<iType2>::value && std::is_integral<iType3>::value && std::is_integral<iType4>::value && std::is_integral<iType5>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 , const iType4 & i4 , const iType5 & i5 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (6 , this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5) )
        return m_map.reference(i0,i1,i2,i3,i4,i5);
      }
  
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3, typename iType4 , typename iType5 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< !(std::is_same<typename drvtraits::specialize , void>::value && std::is_integral<iType0>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 , const iType4 & i4 , const iType5 & i5 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (6 , this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5) )
        return m_map.reference(i0,i1,i2,i3,i4,i5,0);
      }
  
    // Rank 7
    template< typename iType0 , typename iType1 , typename iType2 , typename iType3, typename iType4 , typename iType5 , typename iType6 >
    KOKKOS_INLINE_FUNCTION
    typename std::enable_if< (std::is_integral<iType0>::value  && std::is_integral<iType1>::value && std::is_integral<iType2>::value && std::is_integral<iType3>::value && std::is_integral<iType4>::value && std::is_integral<iType5>::value && std::is_integral<iType6>::value), reference_type>::type
    operator()(const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 , const iType4 & i4 , const iType5 & i5 , const iType6 & i6 ) const
      {
        KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (7 , this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5, i6) )
        return m_map.reference(i0,i1,i2,i3,i4,i5,i6);
      }
  
  #undef KOKKOS_IMPL_VIEW_OPERATOR_VERIFY
  
    //----------------------------------------
    // Standard constructor, destructor, and assignment operators...
  
    KOKKOS_INLINE_FUNCTION
    ~DynRankView() {}
  
    KOKKOS_INLINE_FUNCTION
    DynRankView() : m_track(), m_map(), m_rank() {} //Default ctor
  
    KOKKOS_INLINE_FUNCTION
    DynRankView( const DynRankView & rhs ) : m_track( rhs.m_track ), m_map( rhs.m_map ), m_rank(rhs.m_rank) {}
  
    KOKKOS_INLINE_FUNCTION
    DynRankView( DynRankView && rhs ) : m_track( rhs.m_track ), m_map( rhs.m_map ), m_rank(rhs.m_rank) {}
  
    KOKKOS_INLINE_FUNCTION
    DynRankView & operator = ( const DynRankView & rhs ) { m_track = rhs.m_track; m_map = rhs.m_map; m_rank = rhs.m_rank; return *this; }
  
    KOKKOS_INLINE_FUNCTION
    DynRankView & operator = ( DynRankView && rhs ) { m_track = rhs.m_track; m_map = rhs.m_map; m_rank = rhs.m_rank; return *this; }
  
    //----------------------------------------
    // Compatible view copy constructor and assignment
    // may assign unmanaged from managed.
    template< class RT , class ... RP >
    KOKKOS_INLINE_FUNCTION
    DynRankView( const DynRankView<RT,RP...> & rhs )
      : m_track( rhs.m_track , traits::is_managed )
      , m_map()
      , m_rank(rhs.m_rank)
      {
        typedef typename DynRankView<RT,RP...> ::traits SrcTraits ;
        typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
        static_assert( Mapping::is_assignable , "Incompatible DynRankView copy construction" );
        Mapping::assign( m_map , rhs.m_map , rhs.m_track );
      }
  
    template< class RT , class ... RP >
    KOKKOS_INLINE_FUNCTION
    DynRankView & operator = (const DynRankView<RT,RP...> & rhs )
      {
        typedef typename DynRankView<RT,RP...> ::traits SrcTraits ;
        typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
        static_assert( Mapping::is_assignable , "Incompatible DynRankView copy construction" );
        Mapping::assign( m_map , rhs.m_map , rhs.m_track );
        m_track.assign( rhs.m_track , traits::is_managed );
        m_rank = rhs.rank();
        return *this;
      }
  
  // Experimental
  // Copy/Assign View to DynRankView
    template< class RT , class ... RP >
    KOKKOS_INLINE_FUNCTION
    DynRankView( const View<RT,RP...> & rhs )
      : m_track()
      , m_map()
      , m_rank( rhs.Rank )
      {
        typedef typename View<RT,RP...>::traits  SrcTraits ;
        typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , Kokkos::Experimental::Impl::ViewToDynRankViewTag >  Mapping ;
        static_assert( Mapping::is_assignable , "Incompatible DynRankView copy construction" );
        Mapping::assign( *this , rhs );
      }
  
    template< class RT , class ... RP >
    KOKKOS_INLINE_FUNCTION
    DynRankView & operator = ( const View<RT,RP...> & rhs )
      {
        typedef typename View<RT,RP...>::traits  SrcTraits ;
        typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , Kokkos::Experimental::Impl::ViewToDynRankViewTag >  Mapping ;
        static_assert( Mapping::is_assignable , "Incompatible View to DynRankView copy assignment" );
        Mapping::assign( *this , rhs );
        return *this ;
      }
  
    //----------------------------------------
    // Allocation tracking properties
  
    KOKKOS_INLINE_FUNCTION
    int use_count() const
      { return m_track.use_count(); }
  
    inline
    const std::string label() const
      { return m_track.template get_label< typename traits::memory_space >(); }
  
    //----------------------------------------
    // Allocation according to allocation properties and array layout
    // unused arg_layout dimensions must be set to ~size_t(0) so that rank deduction can properly take place
    template< class ... P >
    explicit inline
    DynRankView( const Impl::ViewCtorProp< P ... > & arg_prop
        , typename std::enable_if< ! Impl::ViewCtorProp< P... >::has_pointer
                                 , typename traits::array_layout
                                 >::type const & arg_layout
        )
        : m_track()
        , m_map()
        , m_rank( Impl::DynRankDimTraits<typename traits::specialize>::template computeRank< typename traits::array_layout, P...>(arg_prop, arg_layout) )
      {
        // Append layout and spaces if not input
        typedef Impl::ViewCtorProp< P ... > alloc_prop_input ;
  
        // use 'std::integral_constant<unsigned,I>' for non-types
        // to avoid duplicate class error.
        typedef Impl::ViewCtorProp
          < P ...
          , typename std::conditional
              < alloc_prop_input::has_label
              , std::integral_constant<unsigned,0>
              , typename std::string
              >::type
          , typename std::conditional
              < alloc_prop_input::has_memory_space
              , std::integral_constant<unsigned,1>
              , typename traits::device_type::memory_space
              >::type
          , typename std::conditional
              < alloc_prop_input::has_execution_space
              , std::integral_constant<unsigned,2>
              , typename traits::device_type::execution_space
              >::type
          > alloc_prop ;
  
        static_assert( traits::is_managed
                     , "View allocation constructor requires managed memory" );
  
        if ( alloc_prop::initialize &&
             ! alloc_prop::execution_space::is_initialized() ) {
          // If initializing view data then
          // the execution space must be initialized.
          Kokkos::Impl::throw_runtime_exception("Constructing DynRankView and initializing data with uninitialized execution space");
        }
  
        // Copy the input allocation properties with possibly defaulted properties
        alloc_prop prop( arg_prop );
  
  //------------------------------------------------------------
  #if defined( KOKKOS_ENABLE_CUDA )
        // If allocating in CudaUVMSpace must fence before and after
        // the allocation to protect against possible concurrent access
        // on the CPU and the GPU.
        // Fence using the trait's executon space (which will be Kokkos::Cuda)
        // to avoid incomplete type errors from usng Kokkos::Cuda directly.
        if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
          traits::device_type::memory_space::execution_space::fence();
        }
  #endif
  //------------------------------------------------------------
  
        Kokkos::Experimental::Impl::SharedAllocationRecord<> *
          record = m_map.allocate_shared( prop , Impl::DynRankDimTraits<typename traits::specialize>::template createLayout<traits, P...>(arg_prop, arg_layout) );
  
  //------------------------------------------------------------
  #if defined( KOKKOS_ENABLE_CUDA )
        if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
          traits::device_type::memory_space::execution_space::fence();
        }
  #endif
  //------------------------------------------------------------
  
        // Setup and initialization complete, start tracking
        m_track.assign_allocated_record_to_uninitialized( record );
      }
  
  
    // Wrappers
    template< class ... P >
    explicit KOKKOS_INLINE_FUNCTION
    DynRankView( const Impl::ViewCtorProp< P ... > & arg_prop
        , typename std::enable_if< Impl::ViewCtorProp< P... >::has_pointer
                                 , typename traits::array_layout
                                 >::type const & arg_layout
        )
        : m_track() // No memory tracking
        , m_map( arg_prop , Impl::DynRankDimTraits<typename traits::specialize>::template createLayout<traits, P...>(arg_prop, arg_layout) )
        , m_rank( Impl::DynRankDimTraits<typename traits::specialize>::template computeRank< typename traits::array_layout, P...>(arg_prop, arg_layout) )
      {
        static_assert(
          std::is_same< pointer_type
                      , typename Impl::ViewCtorProp< P... >::pointer_type
                      >::value ,
          "Constructing DynRankView to wrap user memory must supply matching pointer type" );
      }
  
    //----------------------------------------
    //Constructor(s)
  
    // Simple dimension-only layout
    template< class ... P >
    explicit inline
    DynRankView( const Impl::ViewCtorProp< P ... > & arg_prop
        , typename std::enable_if< ! Impl::ViewCtorProp< P... >::has_pointer
                                 , size_t
                                 >::type const arg_N0 = ~size_t(0)
        , const size_t arg_N1 = ~size_t(0)
        , const size_t arg_N2 = ~size_t(0)
        , const size_t arg_N3 = ~size_t(0)
        , const size_t arg_N4 = ~size_t(0)
        , const size_t arg_N5 = ~size_t(0)
        , const size_t arg_N6 = ~size_t(0)
        , const size_t arg_N7 = ~size_t(0)
        )
      : DynRankView( arg_prop
      , typename traits::array_layout
            ( arg_N0 , arg_N1 , arg_N2 , arg_N3 , arg_N4 , arg_N5 , arg_N6 , arg_N7 )
        )
      {}
  
    template< class ... P >
    explicit KOKKOS_INLINE_FUNCTION
    DynRankView( const Impl::ViewCtorProp< P ... > & arg_prop
        , typename std::enable_if< Impl::ViewCtorProp< P... >::has_pointer
                                 , size_t
                                 >::type const arg_N0 = ~size_t(0)
        , const size_t arg_N1 = ~size_t(0)
        , const size_t arg_N2 = ~size_t(0)
        , const size_t arg_N3 = ~size_t(0)
        , const size_t arg_N4 = ~size_t(0)
        , const size_t arg_N5 = ~size_t(0)
        , const size_t arg_N6 = ~size_t(0)
        , const size_t arg_N7 = ~size_t(0)
        )
      : DynRankView( arg_prop
      , typename traits::array_layout
            ( arg_N0 , arg_N1 , arg_N2 , arg_N3 , arg_N4 , arg_N5 , arg_N6 , arg_N7 )
        )
      {}
  
    // Allocate with label and layout
    template< typename Label >
    explicit inline
    DynRankView( const Label & arg_label
        , typename std::enable_if<
            Kokkos::Experimental::Impl::is_view_label<Label>::value ,
            typename traits::array_layout >::type const & arg_layout
        )
      : DynRankView( Impl::ViewCtorProp< std::string >( arg_label ) , arg_layout )
      {}
  
    // Allocate label and layout, must disambiguate from subview constructor
    template< typename Label >
    explicit inline
    DynRankView( const Label & arg_label
        , typename std::enable_if<
            Kokkos::Experimental::Impl::is_view_label<Label>::value ,
          const size_t >::type arg_N0 = ~size_t(0)
        , const size_t arg_N1 = ~size_t(0)
        , const size_t arg_N2 = ~size_t(0)
        , const size_t arg_N3 = ~size_t(0)
        , const size_t arg_N4 = ~size_t(0)
        , const size_t arg_N5 = ~size_t(0)
        , const size_t arg_N6 = ~size_t(0)
        , const size_t arg_N7 = ~size_t(0)
        )
      : DynRankView( Impl::ViewCtorProp< std::string >( arg_label )
      , typename traits::array_layout
            ( arg_N0 , arg_N1 , arg_N2 , arg_N3 , arg_N4 , arg_N5 , arg_N6 , arg_N7 )
            )
      {}
  
    // For backward compatibility
    // NDE This ctor does not take ViewCtorProp argument - should not use alternative createLayout call
    explicit inline
    DynRankView( const ViewAllocateWithoutInitializing & arg_prop
        , const typename traits::array_layout & arg_layout
        )
      : DynRankView( Impl::ViewCtorProp< std::string , Kokkos::Experimental::Impl::WithoutInitializing_t >( arg_prop.label , Kokkos::Experimental::WithoutInitializing )
            , Impl::DynRankDimTraits<typename traits::specialize>::createLayout(arg_layout)
        )
      {}
  
    explicit inline
    DynRankView( const ViewAllocateWithoutInitializing & arg_prop
        , const size_t arg_N0 = ~size_t(0)
        , const size_t arg_N1 = ~size_t(0)
        , const size_t arg_N2 = ~size_t(0)
        , const size_t arg_N3 = ~size_t(0)
        , const size_t arg_N4 = ~size_t(0)
        , const size_t arg_N5 = ~size_t(0)
        , const size_t arg_N6 = ~size_t(0)
        , const size_t arg_N7 = ~size_t(0)
        )
      : DynRankView(Impl::ViewCtorProp< std::string , Kokkos::Experimental::Impl::WithoutInitializing_t >( arg_prop.label , Kokkos::Experimental::WithoutInitializing ), arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7 )
      {}
  
    //----------------------------------------
    // Memory span required to wrap these dimensions.
    static constexpr size_t required_allocation_size(
                                         const size_t arg_N0 = 0
                                       , const size_t arg_N1 = 0
                                       , const size_t arg_N2 = 0
                                       , const size_t arg_N3 = 0
                                       , const size_t arg_N4 = 0
                                       , const size_t arg_N5 = 0
                                       , const size_t arg_N6 = 0
                                       , const size_t arg_N7 = 0
                                       )
      {
        return map_type::memory_span(
          typename traits::array_layout
            ( arg_N0 , arg_N1 , arg_N2 , arg_N3
            , arg_N4 , arg_N5 , arg_N6 , arg_N7 ) );
      }
  
    explicit KOKKOS_INLINE_FUNCTION
    DynRankView( pointer_type arg_ptr
        , const size_t arg_N0 = ~size_t(0)
        , const size_t arg_N1 = ~size_t(0)
        , const size_t arg_N2 = ~size_t(0)
        , const size_t arg_N3 = ~size_t(0)
        , const size_t arg_N4 = ~size_t(0)
        , const size_t arg_N5 = ~size_t(0)
        , const size_t arg_N6 = ~size_t(0)
        , const size_t arg_N7 = ~size_t(0)
        )
      : DynRankView( Impl::ViewCtorProp<pointer_type>(arg_ptr) , arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7 )
      {}
  
    explicit KOKKOS_INLINE_FUNCTION
    DynRankView( pointer_type arg_ptr
        , typename traits::array_layout & arg_layout
        )
      : DynRankView( Impl::ViewCtorProp<pointer_type>(arg_ptr) , arg_layout )
      {}
  
  
    //----------------------------------------
    // Shared scratch memory constructor
  
    static inline
    size_t shmem_size( const size_t arg_N0 = ~size_t(0) ,
                       const size_t arg_N1 = ~size_t(0) ,
                       const size_t arg_N2 = ~size_t(0) ,
                       const size_t arg_N3 = ~size_t(0) ,
                       const size_t arg_N4 = ~size_t(0) ,
                       const size_t arg_N5 = ~size_t(0) ,
                       const size_t arg_N6 = ~size_t(0) ,
                       const size_t arg_N7 = ~size_t(0) )
    {
      const size_t num_passed_args =
        ( arg_N0 != ~size_t(0) ) + ( arg_N1 != ~size_t(0) ) + ( arg_N2 != ~size_t(0) ) +
        ( arg_N3 != ~size_t(0) ) + ( arg_N4 != ~size_t(0) ) + ( arg_N5 != ~size_t(0) ) +
        ( arg_N6 != ~size_t(0) ) + ( arg_N7 != ~size_t(0) );
  
      if ( std::is_same<typename traits::specialize , void>::value && num_passed_args != traits::rank_dynamic ) {
        Kokkos::abort( "Kokkos::View::shmem_size() rank_dynamic != number of arguments.\n" );
      }
      {}
  
      return map_type::memory_span(
             typename traits::array_layout
              ( arg_N0 , arg_N1 , arg_N2 , arg_N3
              , arg_N4 , arg_N5 , arg_N6 , arg_N7 ) );
    }
  
    explicit KOKKOS_INLINE_FUNCTION
    DynRankView( const typename traits::execution_space::scratch_memory_space & arg_space
        , const typename traits::array_layout & arg_layout )
      : DynRankView( Impl::ViewCtorProp<pointer_type>(
                reinterpret_cast<pointer_type>(
                  arg_space.get_shmem( map_type::memory_span(
                    Impl::DynRankDimTraits<typename traits::specialize>::createLayout( arg_layout ) //is this correct?
                  ) ) ) )
           , arg_layout )
       {}
  
    explicit KOKKOS_INLINE_FUNCTION
    DynRankView( const typename traits::execution_space::scratch_memory_space & arg_space
        , const size_t arg_N0 = ~size_t(0)
        , const size_t arg_N1 = ~size_t(0)
        , const size_t arg_N2 = ~size_t(0)
        , const size_t arg_N3 = ~size_t(0)
        , const size_t arg_N4 = ~size_t(0)
        , const size_t arg_N5 = ~size_t(0)
        , const size_t arg_N6 = ~size_t(0)
        , const size_t arg_N7 = ~size_t(0) )
  
      : DynRankView( Impl::ViewCtorProp<pointer_type>(
                     reinterpret_cast<pointer_type>(
                       arg_space.get_shmem(
                         map_type::memory_span(
                         Impl::DynRankDimTraits<typename traits::specialize>::createLayout(
                         typename traits::array_layout
                         ( arg_N0 , arg_N1 , arg_N2 , arg_N3
                         , arg_N4 , arg_N5 , arg_N6 , arg_N7 ) ) ) ) )
                      )
                    , typename traits::array_layout
                      ( arg_N0 , arg_N1 , arg_N2 , arg_N3
                      , arg_N4 , arg_N5 , arg_N6 , arg_N7 )
          )
      {}
  
  };
  
  
    template < typename D , class ... P >
    KOKKOS_INLINE_FUNCTION
    constexpr unsigned rank( const DynRankView<D , P...> & DRV ) { return DRV.rank(); } //needed for transition to common constexpr method in view and dynrankview to return rank
  
  //----------------------------------------------------------------------------
  // Subview mapping.
  // Deduce destination view type from source view traits and subview arguments
  
  namespace Impl {
  
  struct DynRankSubviewTag {};
  
  } // namespace Impl
  } // namespace Experimental
  
  namespace Impl {
  
  template< class SrcTraits , class ... Args >
  struct ViewMapping
    < typename std::enable_if<(
        std::is_same< typename SrcTraits::specialize , void >::value
        &&
        (
          std::is_same< typename SrcTraits::array_layout
                      , Kokkos::LayoutLeft >::value ||
          std::is_same< typename SrcTraits::array_layout
                      , Kokkos::LayoutRight >::value ||
          std::is_same< typename SrcTraits::array_layout
                      , Kokkos::LayoutStride >::value
        )
      ), Kokkos::Experimental::Impl::DynRankSubviewTag >::type
    , SrcTraits
    , Args ... >
  {
  private:
  
    enum
      { RZ = false
      , R0 = bool(is_integral_extent<0,Args...>::value)
      , R1 = bool(is_integral_extent<1,Args...>::value)
      , R2 = bool(is_integral_extent<2,Args...>::value)
      , R3 = bool(is_integral_extent<3,Args...>::value)
      , R4 = bool(is_integral_extent<4,Args...>::value)
      , R5 = bool(is_integral_extent<5,Args...>::value)
      , R6 = bool(is_integral_extent<6,Args...>::value)
      };
  
    enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
                + unsigned(R4) + unsigned(R5) + unsigned(R6) };
  
    typedef Kokkos::LayoutStride array_layout ;
  
    typedef typename SrcTraits::value_type  value_type ;
  
    typedef value_type******* data_type ;
  
  public:
  
    typedef Kokkos::ViewTraits
      < data_type
      , array_layout
      , typename SrcTraits::device_type
      , typename SrcTraits::memory_traits > traits_type ;
  
    typedef Kokkos::View
      < data_type
      , array_layout
      , typename SrcTraits::device_type
      , typename SrcTraits::memory_traits > type ;
  
  
    template< class MemoryTraits >
    struct apply {
  
      static_assert( Kokkos::Impl::is_memory_traits< MemoryTraits >::value , "" );
  
      typedef Kokkos::ViewTraits
        < data_type
        , array_layout
        , typename SrcTraits::device_type
        , MemoryTraits > traits_type ;
  
      typedef Kokkos::View
        < data_type
        , array_layout
        , typename SrcTraits::device_type
        , MemoryTraits > type ;
    };
  
  
    typedef typename SrcTraits::dimension dimension ;
  
    template < class Arg0 = int, class Arg1 = int, class Arg2 = int, class Arg3 = int, class Arg4 = int, class Arg5 = int, class Arg6 = int >
    struct ExtentGenerator {
      KOKKOS_INLINE_FUNCTION
      static SubviewExtents< 7 , rank > generator ( const dimension & dim , Arg0 arg0 = Arg0(), Arg1 arg1 = Arg1(), Arg2 arg2 = Arg2(), Arg3 arg3 = Arg3(), Arg4 arg4 = Arg4(), Arg5 arg5 = Arg5(), Arg6 arg6 = Arg6() )
      {
         return SubviewExtents< 7 , rank>( dim , arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
      }
    };
  
  
    typedef Kokkos::Experimental::DynRankView< value_type , array_layout , typename SrcTraits::device_type , typename SrcTraits::memory_traits >  ret_type;
  
    template < typename T , class ... P >
    KOKKOS_INLINE_FUNCTION
    static ret_type subview( const unsigned src_rank , Kokkos::Experimental::DynRankView< T , P...> const & src
                      , Args ... args )
      {
  
         typedef ViewMapping< traits_type, void >  DstType ;
  
         typedef typename std::conditional< (rank==0) , ViewDimension<>
                                                      , typename std::conditional< (rank==1) , ViewDimension<0>
                                                      , typename std::conditional< (rank==2) , ViewDimension<0,0>
                                                      , typename std::conditional< (rank==3) , ViewDimension<0,0,0>
                                                      , typename std::conditional< (rank==4) , ViewDimension<0,0,0,0>
                                                      , typename std::conditional< (rank==5) , ViewDimension<0,0,0,0,0>
                                                      , typename std::conditional< (rank==6) , ViewDimension<0,0,0,0,0,0>
                                                                                             , ViewDimension<0,0,0,0,0,0,0>
                                                      >::type >::type >::type >::type >::type >::type >::type  DstDimType ;
  
        typedef ViewOffset< DstDimType , Kokkos::LayoutStride > dst_offset_type ;
        typedef typename DstType::handle_type  dst_handle_type ;
  
        ret_type dst ;
  
        const SubviewExtents< 7 , rank > extents =
          ExtentGenerator< Args ... >::generator( src.m_map.m_offset.m_dim , args... ) ;
  
        dst_offset_type tempdst( src.m_map.m_offset , extents ) ;
  
        dst.m_track = src.m_track ;
  
        dst.m_map.m_offset.m_dim.N0 = tempdst.m_dim.N0 ;
        dst.m_map.m_offset.m_dim.N1 = tempdst.m_dim.N1 ;
        dst.m_map.m_offset.m_dim.N2 = tempdst.m_dim.N2 ;
        dst.m_map.m_offset.m_dim.N3 = tempdst.m_dim.N3 ;
        dst.m_map.m_offset.m_dim.N4 = tempdst.m_dim.N4 ;
        dst.m_map.m_offset.m_dim.N5 = tempdst.m_dim.N5 ;
        dst.m_map.m_offset.m_dim.N6 = tempdst.m_dim.N6 ;
  
        dst.m_map.m_offset.m_stride.S0 = tempdst.m_stride.S0 ;
        dst.m_map.m_offset.m_stride.S1 = tempdst.m_stride.S1 ;
        dst.m_map.m_offset.m_stride.S2 = tempdst.m_stride.S2 ;
        dst.m_map.m_offset.m_stride.S3 = tempdst.m_stride.S3 ;
        dst.m_map.m_offset.m_stride.S4 = tempdst.m_stride.S4 ;
        dst.m_map.m_offset.m_stride.S5 = tempdst.m_stride.S5 ;
        dst.m_map.m_offset.m_stride.S6 = tempdst.m_stride.S6 ;
  
        dst.m_map.m_handle = dst_handle_type( src.m_map.m_handle +
                                        src.m_map.m_offset( extents.domain_offset(0)
                                                    , extents.domain_offset(1)
                                                    , extents.domain_offset(2)
                                                    , extents.domain_offset(3)
                                                    , extents.domain_offset(4)
                                                    , extents.domain_offset(5)
                                                    , extents.domain_offset(6)
                                                    ) );
  
        dst.m_rank = ( src_rank > 0 ? unsigned(R0) : 0 )
                   + ( src_rank > 1 ? unsigned(R1) : 0 )
                   + ( src_rank > 2 ? unsigned(R2) : 0 )
                   + ( src_rank > 3 ? unsigned(R3) : 0 )
                   + ( src_rank > 4 ? unsigned(R4) : 0 )
                   + ( src_rank > 5 ? unsigned(R5) : 0 )
                   + ( src_rank > 6 ? unsigned(R6) : 0 ) ;
  
        return dst ;
      }
  };
  
  } // end Impl
  
  namespace Experimental {
  
  template< class V , class ... Args >
  using Subdynrankview = typename Kokkos::Impl::ViewMapping< Kokkos::Experimental::Impl::DynRankSubviewTag , V , Args... >::ret_type ;
  
  template< class D , class ... P , class ...Args >
  KOKKOS_INLINE_FUNCTION
  Subdynrankview< ViewTraits<D******* , P...> , Args... >
  subdynrankview( const Kokkos::Experimental::DynRankView< D , P... > &src , Args...args)
    {
      if ( src.rank() > sizeof...(Args) ) //allow sizeof...(Args) >= src.rank(), ignore the remaining args
        { Kokkos::abort("subdynrankview: num of args must be >= rank of the source DynRankView"); }
  
      typedef Kokkos::Impl::ViewMapping< Kokkos::Experimental::Impl::DynRankSubviewTag , Kokkos::ViewTraits< D*******, P... > , Args... > metafcn ;
  
      return metafcn::subview( src.rank() , src , args... );
    }
  
  //Wrapper to allow subview function name
  template< class D , class ... P , class ...Args >
  KOKKOS_INLINE_FUNCTION
  Subdynrankview< ViewTraits<D******* , P...> , Args... >
  subview( const Kokkos::Experimental::DynRankView< D , P... > &src , Args...args)
    {
      return subdynrankview( src , args... );
    }
  
  } // namespace Experimental
  } // namespace Kokkos
  
  namespace Kokkos {
  namespace Experimental {
  
  // overload == and !=
  template< class LT , class ... LP , class RT , class ... RP >
  KOKKOS_INLINE_FUNCTION
  bool operator == ( const DynRankView<LT,LP...> & lhs ,
                     const DynRankView<RT,RP...> & rhs )
  {
    // Same data, layout, dimensions
    typedef ViewTraits<LT,LP...>  lhs_traits ;
    typedef ViewTraits<RT,RP...>  rhs_traits ;
  
    return
      std::is_same< typename lhs_traits::const_value_type ,
                    typename rhs_traits::const_value_type >::value &&
      std::is_same< typename lhs_traits::array_layout ,
                    typename rhs_traits::array_layout >::value &&
      std::is_same< typename lhs_traits::memory_space ,
                    typename rhs_traits::memory_space >::value &&
      lhs.rank()       ==  rhs.rank() &&
      lhs.data()       == rhs.data() &&
      lhs.span()       == rhs.span() &&
      lhs.dimension(0) == rhs.dimension(0) &&
      lhs.dimension(1) == rhs.dimension(1) &&
      lhs.dimension(2) == rhs.dimension(2) &&
      lhs.dimension(3) == rhs.dimension(3) &&
      lhs.dimension(4) == rhs.dimension(4) &&
      lhs.dimension(5) == rhs.dimension(5) &&
      lhs.dimension(6) == rhs.dimension(6) &&
      lhs.dimension(7) == rhs.dimension(7);
  }
  
  template< class LT , class ... LP , class RT , class ... RP >
  KOKKOS_INLINE_FUNCTION
  bool operator != ( const DynRankView<LT,LP...> & lhs ,
                     const DynRankView<RT,RP...> & rhs )
  {
    return ! ( operator==(lhs,rhs) );
  }
  
  } //end Experimental
  } //end Kokkos
  
  //----------------------------------------------------------------------------
  //----------------------------------------------------------------------------
  namespace Kokkos {
  namespace Experimental {
  namespace Impl {
  
  template< class OutputView , typename Enable = void >
  struct DynRankViewFill {
  
    typedef typename OutputView::traits::const_value_type  const_value_type ;
  
    const OutputView output ;
    const_value_type input ;
  
    KOKKOS_INLINE_FUNCTION
    void operator()( const size_t i0 ) const
    {
      const size_t n1 = output.dimension_1();
      const size_t n2 = output.dimension_2();
      const size_t n3 = output.dimension_3();
      const size_t n4 = output.dimension_4();
      const size_t n5 = output.dimension_5();
      const size_t n6 = output.dimension_6();
  
      for ( size_t i1 = 0 ; i1 < n1 ; ++i1 ) {
      for ( size_t i2 = 0 ; i2 < n2 ; ++i2 ) {
      for ( size_t i3 = 0 ; i3 < n3 ; ++i3 ) {
      for ( size_t i4 = 0 ; i4 < n4 ; ++i4 ) {
      for ( size_t i5 = 0 ; i5 < n5 ; ++i5 ) {
      for ( size_t i6 = 0 ; i6 < n6 ; ++i6 ) {
        output(i0,i1,i2,i3,i4,i5,i6) = input ;
      }}}}}}
    }
  
    DynRankViewFill( const OutputView & arg_out , const_value_type & arg_in )
      : output( arg_out ), input( arg_in )
      {
        typedef typename OutputView::execution_space  execution_space ;
        typedef Kokkos::RangePolicy< execution_space > Policy ;
  
        const Kokkos::Impl::ParallelFor< DynRankViewFill , Policy > closure( *this , Policy( 0 , output.dimension_0() ) );
  
        closure.execute();
  
        execution_space::fence();
      }
  };
  
  template< class OutputView >
  struct DynRankViewFill< OutputView , typename std::enable_if< OutputView::Rank == 0 >::type > {
    DynRankViewFill( const OutputView & dst , const typename OutputView::const_value_type & src )
      {
        Kokkos::Impl::DeepCopy< typename OutputView::memory_space , Kokkos::HostSpace >
          ( dst.data() , & src , sizeof(typename OutputView::const_value_type) );
      }
  };
  
  template< class OutputView , class InputView , class ExecSpace = typename OutputView::execution_space >
  struct DynRankViewRemap {
  
    const OutputView output ;
    const InputView  input ;
    const size_t n0 ;
    const size_t n1 ;
    const size_t n2 ;
    const size_t n3 ;
    const size_t n4 ;
    const size_t n5 ;
    const size_t n6 ;
    const size_t n7 ;
  
    DynRankViewRemap( const OutputView & arg_out , const InputView & arg_in )
      : output( arg_out ), input( arg_in )
      , n0( std::min( (size_t)arg_out.dimension_0() , (size_t)arg_in.dimension_0() ) )
      , n1( std::min( (size_t)arg_out.dimension_1() , (size_t)arg_in.dimension_1() ) )
      , n2( std::min( (size_t)arg_out.dimension_2() , (size_t)arg_in.dimension_2() ) )
      , n3( std::min( (size_t)arg_out.dimension_3() , (size_t)arg_in.dimension_3() ) )
      , n4( std::min( (size_t)arg_out.dimension_4() , (size_t)arg_in.dimension_4() ) )
      , n5( std::min( (size_t)arg_out.dimension_5() , (size_t)arg_in.dimension_5() ) )
      , n6( std::min( (size_t)arg_out.dimension_6() , (size_t)arg_in.dimension_6() ) )
      , n7( std::min( (size_t)arg_out.dimension_7() , (size_t)arg_in.dimension_7() ) )
      {
        typedef Kokkos::RangePolicy< ExecSpace > Policy ;
        const Kokkos::Impl::ParallelFor< DynRankViewRemap , Policy > closure( *this , Policy( 0 , n0 ) );
        closure.execute();
      }
  
    KOKKOS_INLINE_FUNCTION
    void operator()( const size_t i0 ) const
    {
      for ( size_t i1 = 0 ; i1 < n1 ; ++i1 ) {
      for ( size_t i2 = 0 ; i2 < n2 ; ++i2 ) {
      for ( size_t i3 = 0 ; i3 < n3 ; ++i3 ) {
      for ( size_t i4 = 0 ; i4 < n4 ; ++i4 ) {
      for ( size_t i5 = 0 ; i5 < n5 ; ++i5 ) {
      for ( size_t i6 = 0 ; i6 < n6 ; ++i6 ) {
        output(i0,i1,i2,i3,i4,i5,i6) = input(i0,i1,i2,i3,i4,i5,i6);
      }}}}}}
    }
  };
  
  } /* namespace Impl */
  } /* namespace Experimental */
  } /* namespace Kokkos */
  
  
  namespace Kokkos {
  namespace Experimental {
  
  /** \brief  Deep copy a value from Host memory into a view.  */
  template< class DT , class ... DP >
  inline
  void deep_copy
    ( const DynRankView<DT,DP...> & dst
    , typename ViewTraits<DT,DP...>::const_value_type & value
    , typename std::enable_if<
      std::is_same< typename ViewTraits<DT,DP...>::specialize , void >::value
      >::type * = 0 )
  {
    static_assert(
      std::is_same< typename ViewTraits<DT,DP...>::non_const_value_type ,
                    typename ViewTraits<DT,DP...>::value_type >::value
      , "deep_copy requires non-const type" );
  
    Kokkos::Experimental::Impl::DynRankViewFill< DynRankView<DT,DP...> >( dst , value );
  }
  
  /** \brief  Deep copy into a value in Host memory from a view.  */
  template< class ST , class ... SP >
  inline
  void deep_copy
    ( typename ViewTraits<ST,SP...>::non_const_value_type & dst
    , const DynRankView<ST,SP...> & src
    , typename std::enable_if<
      std::is_same< typename ViewTraits<ST,SP...>::specialize , void >::value
      >::type * = 0 )
  {
    if ( src.rank() != 0 )
    {
      Kokkos::abort("");
    }
  
    typedef ViewTraits<ST,SP...>               src_traits ;
    typedef typename src_traits::memory_space  src_memory_space ;
    Kokkos::Impl::DeepCopy< HostSpace , src_memory_space >( & dst , src.data() , sizeof(ST) );
  }
  
  //----------------------------------------------------------------------------
  /** \brief  A deep copy between views of the default specialization, compatible type,
   *          same rank, same contiguous layout.
   */
  template< class DstType , class SrcType >
  inline
  void deep_copy
    ( const DstType & dst
    , const SrcType & src
    , typename std::enable_if<(
      std::is_same< typename DstType::traits::specialize , void >::value &&
      std::is_same< typename SrcType::traits::specialize , void >::value
      &&
      ( Kokkos::Experimental::is_dyn_rank_view<DstType>::value || Kokkos::Experimental::is_dyn_rank_view<SrcType>::value)
    )>::type * = 0 )
  {
    static_assert(
      std::is_same< typename DstType::traits::value_type ,
                    typename DstType::traits::non_const_value_type >::value
      , "deep_copy requires non-const destination type" );
  
    typedef DstType  dst_type ;
    typedef SrcType  src_type ;
  
    typedef typename dst_type::execution_space  dst_execution_space ;
    typedef typename src_type::execution_space  src_execution_space ;
    typedef typename dst_type::memory_space     dst_memory_space ;
    typedef typename src_type::memory_space     src_memory_space ;
  
    enum { DstExecCanAccessSrc =
     Kokkos::Impl::SpaceAccessibility< dst_execution_space , src_memory_space >::accessible };
  
    enum { SrcExecCanAccessDst =
     Kokkos::Impl::SpaceAccessibility< src_execution_space , dst_memory_space >::accessible };
  
    if ( (void *) dst.data() != (void*) src.data() ) {
  
      // Concern: If overlapping views then a parallel copy will be erroneous.
      // ...
  
      // If same type, equal layout, equal dimensions, equal span, and contiguous memory then can byte-wise copy
      if ( rank(src) == 0 && rank(dst) == 0 )
      {
        typedef typename dst_type::value_type    value_type ;
        Kokkos::Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.data() , src.data() , sizeof(value_type) );
      }
      else if ( std::is_same< typename DstType::traits::value_type ,
                         typename SrcType::traits::non_const_value_type >::value &&
           (
             ( std::is_same< typename DstType::traits::array_layout ,
                             typename SrcType::traits::array_layout >::value
               &&
               ( std::is_same< typename DstType::traits::array_layout ,
                               typename Kokkos::LayoutLeft>::value
               ||
                 std::is_same< typename DstType::traits::array_layout ,
                               typename Kokkos::LayoutRight>::value
               )
             )
             ||
             (
               rank(dst) == 1
               &&
               rank(src) == 1
             )
           ) &&
           dst.span_is_contiguous() &&
           src.span_is_contiguous() &&
           dst.span() == src.span() &&
           dst.dimension_0() == src.dimension_0() &&
           dst.dimension_1() == src.dimension_1() &&
           dst.dimension_2() == src.dimension_2() &&
           dst.dimension_3() == src.dimension_3() &&
           dst.dimension_4() == src.dimension_4() &&
           dst.dimension_5() == src.dimension_5() &&
           dst.dimension_6() == src.dimension_6() &&
           dst.dimension_7() == src.dimension_7() ) {
  
        const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
  
        Kokkos::Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.data() , src.data() , nbytes );
      }
      else if ( std::is_same< typename DstType::traits::value_type ,
                              typename SrcType::traits::non_const_value_type >::value &&
           (
             ( std::is_same< typename DstType::traits::array_layout ,
                             typename SrcType::traits::array_layout >::value
               &&
               std::is_same< typename DstType::traits::array_layout ,
                            typename Kokkos::LayoutStride>::value
             )
             ||
             (
               rank(dst) == 1
               &&
               rank(src) == 1
             )
           ) &&
           dst.span_is_contiguous() &&
           src.span_is_contiguous() &&
           dst.span() == src.span() &&
           dst.dimension_0() == src.dimension_0() &&
           dst.dimension_1() == src.dimension_1() &&
           dst.dimension_2() == src.dimension_2() &&
           dst.dimension_3() == src.dimension_3() &&
           dst.dimension_4() == src.dimension_4() &&
           dst.dimension_5() == src.dimension_5() &&
           dst.dimension_6() == src.dimension_6() &&
           dst.dimension_7() == src.dimension_7() &&
           dst.stride_0() == src.stride_0() &&
           dst.stride_1() == src.stride_1() &&
           dst.stride_2() == src.stride_2() &&
           dst.stride_3() == src.stride_3() &&
           dst.stride_4() == src.stride_4() &&
           dst.stride_5() == src.stride_5() &&
           dst.stride_6() == src.stride_6() &&
           dst.stride_7() == src.stride_7()
           ) {
  
        const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
  
        Kokkos::Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.data() , src.data() , nbytes );
      }
      else if ( DstExecCanAccessSrc ) {
        // Copying data between views in accessible memory spaces and either non-contiguous or incompatible shape.
        Kokkos::Experimental::Impl::DynRankViewRemap< dst_type , src_type >( dst , src );
      }
      else if ( SrcExecCanAccessDst ) {
        // Copying data between views in accessible memory spaces and either non-contiguous or incompatible shape.
        Kokkos::Experimental::Impl::DynRankViewRemap< dst_type , src_type , src_execution_space >( dst , src );
      }
      else {
        Kokkos::Impl::throw_runtime_exception("deep_copy given views that would require a temporary allocation");
      }
    }
  }
  
  } //end Experimental
  } //end Kokkos
  
  
  //----------------------------------------------------------------------------
  //----------------------------------------------------------------------------
  
  namespace Kokkos {
  namespace Experimental {
  
  namespace Impl {
  
  
  // Deduce Mirror Types
  template<class Space, class T, class ... P>
  struct MirrorDRViewType {
    // The incoming view_type
    typedef typename Kokkos::Experimental::DynRankView<T,P...> src_view_type;
    // The memory space for the mirror view
    typedef typename Space::memory_space memory_space;
    // Check whether it is the same memory space
    enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
    // The array_layout
    typedef typename src_view_type::array_layout array_layout;
    // The data type (we probably want it non-const since otherwise we can't even deep_copy to it.
    typedef typename src_view_type::non_const_data_type data_type;
    // The destination view type if it is not the same memory space
    typedef Kokkos::Experimental::DynRankView<data_type,array_layout,Space> dest_view_type;
    // If it is the same memory_space return the existsing view_type
    // This will also keep the unmanaged trait if necessary
    typedef typename std::conditional<is_same_memspace,src_view_type,dest_view_type>::type view_type;
  };
  
  template<class Space, class T, class ... P>
  struct MirrorDRVType {
    // The incoming view_type
    typedef typename Kokkos::Experimental::DynRankView<T,P...> src_view_type;
    // The memory space for the mirror view
    typedef typename Space::memory_space memory_space;
    // Check whether it is the same memory space
    enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
    // The array_layout
    typedef typename src_view_type::array_layout array_layout;
    // The data type (we probably want it non-const since otherwise we can't even deep_copy to it.
    typedef typename src_view_type::non_const_data_type data_type;
    // The destination view type if it is not the same memory space
    typedef Kokkos::Experimental::DynRankView<data_type,array_layout,Space> view_type;
  };
  
  }
  
  
  template< class T , class ... P >
  inline
  typename DynRankView<T,P...>::HostMirror
  create_mirror( const DynRankView<T,P...> & src
               , typename std::enable_if<
                   ! std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout
                                 , Kokkos::LayoutStride >::value
                 >::type * = 0
               )
  {
    typedef DynRankView<T,P...>                   src_type ;
    typedef typename src_type::HostMirror  dst_type ;
  
    return dst_type( std::string( src.label() ).append("_mirror")
                   , Impl::reconstructLayout(src.layout(), src.rank()) );
  }
  
  
  template< class T , class ... P >
  inline
  typename DynRankView<T,P...>::HostMirror
  create_mirror( const DynRankView<T,P...> & src
               , typename std::enable_if<
                   std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout
                               , Kokkos::LayoutStride >::value
                 >::type * = 0
               )
  {
    typedef DynRankView<T,P...>                   src_type ;
    typedef typename src_type::HostMirror  dst_type ;
  
    return dst_type( std::string( src.label() ).append("_mirror")
                   , Impl::reconstructLayout(src.layout(), src.rank()) );
  }
  
  
  // Create a mirror in a new space (specialization for different space)
  template<class Space, class T, class ... P>
  typename Impl::MirrorDRVType<Space,T,P ...>::view_type create_mirror(const Space& , const Kokkos::Experimental::DynRankView<T,P...> & src) {
    return typename Impl::MirrorDRVType<Space,T,P ...>::view_type(src.label(), Impl::reconstructLayout(src.layout(), src.rank()) );
  }
  
  template< class T , class ... P >
  inline
  typename DynRankView<T,P...>::HostMirror
  create_mirror_view( const DynRankView<T,P...> & src
                    , typename std::enable_if<(
                        std::is_same< typename DynRankView<T,P...>::memory_space
                                    , typename DynRankView<T,P...>::HostMirror::memory_space
                                    >::value
                        &&
                        std::is_same< typename DynRankView<T,P...>::data_type
                                    , typename DynRankView<T,P...>::HostMirror::data_type
                                    >::value
                      )>::type * = 0
                    )
  {
    return src ;
  }
  
  template< class T , class ... P >
  inline
  typename DynRankView<T,P...>::HostMirror
  create_mirror_view( const DynRankView<T,P...> & src
                    , typename std::enable_if< ! (
                        std::is_same< typename DynRankView<T,P...>::memory_space
                                    , typename DynRankView<T,P...>::HostMirror::memory_space
                                    >::value
                        &&
                        std::is_same< typename DynRankView<T,P...>::data_type
                                    , typename DynRankView<T,P...>::HostMirror::data_type
                                    >::value
                      )>::type * = 0
                    )
  {
    return Kokkos::Experimental::create_mirror( src );
  }
  
  // Create a mirror view in a new space (specialization for same space)
  template<class Space, class T, class ... P>
  typename Impl::MirrorDRViewType<Space,T,P ...>::view_type
  create_mirror_view(const Space& , const Kokkos::Experimental::DynRankView<T,P...> & src
    , typename std::enable_if<Impl::MirrorDRViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
    return src;
  }
  
  // Create a mirror view in a new space (specialization for different space)
  template<class Space, class T, class ... P>
  typename Impl::MirrorDRViewType<Space,T,P ...>::view_type
  create_mirror_view(const Space& , const Kokkos::Experimental::DynRankView<T,P...> & src
    , typename std::enable_if<!Impl::MirrorDRViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
    return typename Impl::MirrorDRViewType<Space,T,P ...>::view_type(src.label(), Impl::reconstructLayout(src.layout(), src.rank()) );
  }
  
  } //end Experimental
  } //end Kokkos
  
  
  //----------------------------------------------------------------------------
  //----------------------------------------------------------------------------
  
  namespace Kokkos {
  namespace Experimental {
  /** \brief  Resize a view with copying old data to new data at the corresponding indices. */
  template< class T , class ... P >
  inline
  void resize( DynRankView<T,P...> & v ,
               const size_t n0 = ~size_t(0) ,
               const size_t n1 = ~size_t(0) ,
               const size_t n2 = ~size_t(0) ,
               const size_t n3 = ~size_t(0) ,
               const size_t n4 = ~size_t(0) ,
               const size_t n5 = ~size_t(0) ,
               const size_t n6 = ~size_t(0) ,
               const size_t n7 = ~size_t(0) )
  {
    typedef DynRankView<T,P...>  drview_type ;
  
    static_assert( Kokkos::ViewTraits<T,P...>::is_managed , "Can only resize managed views" );
  
    drview_type v_resized( v.label(), n0, n1, n2, n3, n4, n5, n6 );
  
    Kokkos::Experimental::Impl::DynRankViewRemap< drview_type , drview_type >( v_resized, v );
  
    v = v_resized ;
  }
  
  /** \brief  Resize a view with copying old data to new data at the corresponding indices. */
  template< class T , class ... P >
  inline
  void realloc( DynRankView<T,P...> & v ,
                const size_t n0 = ~size_t(0) ,
                const size_t n1 = ~size_t(0) ,
                const size_t n2 = ~size_t(0) ,
                const size_t n3 = ~size_t(0) ,
                const size_t n4 = ~size_t(0) ,
                const size_t n5 = ~size_t(0) ,
                const size_t n6 = ~size_t(0) ,
                const size_t n7 = ~size_t(0) )
  {
    typedef DynRankView<T,P...>  drview_type ;
  
    static_assert( Kokkos::ViewTraits<T,P...>::is_managed , "Can only realloc managed views" );
  
    const std::string label = v.label();
  
    v = drview_type(); // Deallocate first, if the only view to allocation
    v = drview_type( label, n0, n1, n2, n3, n4, n5, n6 );
  }
  
  } //end Experimental
  
  } //end Kokkos
  
  using Kokkos::Experimental::is_dyn_rank_view ;
  
  namespace Kokkos {
  
  template< typename D , class ... P >
  using DynRankView = Kokkos::Experimental::DynRankView< D , P... > ;
  
  using Kokkos::Experimental::deep_copy ;
  using Kokkos::Experimental::create_mirror ;
  using Kokkos::Experimental::create_mirror_view ;
  using Kokkos::Experimental::subdynrankview ;
  using Kokkos::Experimental::subview ;
  using Kokkos::Experimental::resize ;
  using Kokkos::Experimental::realloc ;
  
  } //end Kokkos
  #endif
  
  