8 #ifndef KOKKOS_OFFSETVIEW_HPP_
9 #define KOKKOS_OFFSETVIEW_HPP_
12 #include <Kokkos_Core.hpp>
14 #include <Kokkos_View.hpp>
18 namespace Experimental {
22 template<
class DataType ,
class ... Properties >
25 template<
class >
struct is_offset_view :
public std::false_type {};
27 template<
class D,
class ... P >
28 struct is_offset_view< OffsetView<D,P...> > :
public std::true_type {};
30 template<
class D,
class ... P >
31 struct is_offset_view< const OffsetView<D,P...> > :
public std::true_type {};
33 #define KOKKOS_INVALID_OFFSET int64_t(0)
34 #define KOKKOS_INVALID_INDEX_RANGE {KOKKOS_INVALID_OFFSET, KOKKOS_INVALID_OFFSET}
36 template <typename iType, typename std::enable_if< std::is_integral<iType>::value &&
37 std::is_signed<iType>::value, iType >::type = 0>
41 using index_list_type = std::initializer_list<int64_t>;
50 template<
class ViewType>
51 struct GetOffsetViewTypeFromViewType {
53 typedef OffsetView<
typename ViewType::data_type,
typename ViewType::array_layout,
54 typename ViewType::device_type,
typename ViewType::memory_traits> type;
58 template<
unsigned ,
class MapType,
class BeginsType >
59 KOKKOS_INLINE_FUNCTION
60 bool offsetview_verify_operator_bounds(
const MapType &,
const BeginsType & )
63 template<
unsigned R ,
class MapType ,
class BeginsType,
class iType ,
class ... Args >
64 KOKKOS_INLINE_FUNCTION
65 bool offsetview_verify_operator_bounds
67 ,
const BeginsType & begins
73 const bool legalIndex = ( int64_t(i) >= begins[R] ) &&
74 ( int64_t(i) <= int64_t(begins[R] + map.extent(R) - 1) );
76 && offsetview_verify_operator_bounds<R+1>( map , begins, args ... );
78 template<
unsigned ,
class MapType,
class BeginsType >
80 void offsetview_error_operator_bounds(
char * ,
int ,
const MapType & ,
const BeginsType &)
83 template<
unsigned R ,
class MapType ,
class BeginsType ,
class iType ,
class ... Args >
85 void offsetview_error_operator_bounds
89 ,
const BeginsType begins
94 const int64_t b = begins[R];
95 const int64_t e = b + map.extent(R) - 1;
97 snprintf(buf,len,
" %ld <= %ld <= %ld %c"
98 , static_cast<unsigned long>(b)
99 , static_cast<unsigned long>(i)
100 , static_cast<unsigned long>(e)
101 , (
sizeof...(Args) ?
',' :
')' )
103 offsetview_error_operator_bounds<R+1>(buf+n,len-n,map,begins,args...);
106 template<
class MemorySpace ,
class MapType ,
class BeginsType,
class ... Args >
107 KOKKOS_INLINE_FUNCTION
108 void offsetview_verify_operator_bounds
109 ( Kokkos::Impl::SharedAllocationTracker
const & tracker
110 ,
const MapType & map ,
const BeginsType & begins, Args ... args )
112 if ( ! offsetview_verify_operator_bounds<0>( map , begins, args ... ) ) {
113 #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
116 const std::string label = tracker.template get_label<MemorySpace>();
117 int n = snprintf(buffer,LEN,
"OffsetView bounds error of view labeled %s (",label.c_str());
118 offsetview_error_operator_bounds<0>( buffer + n , LEN - n , map ,begins, args ... );
119 Kokkos::Impl::throw_runtime_exception(std::string(buffer));
126 if (tracker.has_record()) {
127 Kokkos::Impl::operator_bounds_error_on_device<MapType>(
128 map, Kokkos::Impl::has_printable_label_typedef<MapType>());
130 Kokkos::abort(
"OffsetView bounds error");
136 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
137 KOKKOS_INLINE_FUNCTION
138 void runtime_check_rank_host(
const size_t rank_dynamic,
const size_t rank,
139 const index_list_type minIndices,
const std::string & label)
142 std::string message =
"Kokkos::Experimental::OffsetView ERROR: for OffsetView labeled '" + label +
"':";
143 if (rank_dynamic != rank) {
144 message +=
"The full rank must be the same as the dynamic rank. full rank = ";
145 message += std::to_string(rank) +
" dynamic rank = " + std::to_string(rank_dynamic) +
"\n";
149 size_t numOffsets = 0;
150 for(
size_t i = 0; i < minIndices.size(); ++i ){
151 if( minIndices.begin()[i] != -KOKKOS_INVALID_OFFSET) numOffsets++;
153 if (numOffsets != rank_dynamic) {
154 message +=
"The number of offsets provided ( " + std::to_string(numOffsets) +
155 " ) must equal the dynamic rank ( " + std::to_string(rank_dynamic) +
" ).";
159 if(isBad) Kokkos::abort(message.c_str());
163 KOKKOS_INLINE_FUNCTION
164 void runtime_check_rank_device(
const size_t rank_dynamic,
const size_t rank,
165 const index_list_type minIndices)
167 if (rank_dynamic != rank) {
168 Kokkos::abort(
"The full rank of an OffsetView must be the same as the dynamic rank.");
170 size_t numOffsets = 0;
171 for(
size_t i = 0; i < minIndices.size(); ++i ){
172 if( minIndices.begin()[i] != -KOKKOS_INVALID_OFFSET) numOffsets++;
174 if (numOffsets != rank) {
175 Kokkos::abort(
"The number of offsets provided to an OffsetView constructor must equal the dynamic rank.");
181 template<
class DataType ,
class ... Properties >
182 class OffsetView :
public ViewTraits< DataType , Properties ... > {
185 typedef ViewTraits< DataType , Properties ... > traits ;
191 template< class ,
class ... >
friend class OffsetView ;
192 template< class ,
class ... >
friend class View ;
193 template< class ,
class ... >
friend class Kokkos::Impl::ViewMapping ;
196 typedef Kokkos::Impl::ViewMapping< traits , void > map_type ;
197 typedef Kokkos::Impl::SharedAllocationTracker track_type ;
199 enum { Rank = map_type::Rank };
203 template <typename iType, typename std::enable_if< std::is_integral<iType>::value, iType>::type = 0>
204 KOKKOS_INLINE_FUNCTION
205 int64_t begin(
const iType dimension)
const {
206 return dimension < Rank ? m_begins[dimension] : 0;
209 KOKKOS_INLINE_FUNCTION
210 begins_type begins()
const {
return m_begins;}
212 template <typename iType, typename std::enable_if< std::is_integral<iType>::value, iType>::type = 0>
213 KOKKOS_INLINE_FUNCTION
214 int64_t end(
const iType dimension)
const {
return begin(dimension) + m_map.extent(dimension);}
220 begins_type m_begins;
225 typedef OffsetView<
typename traits::scalar_array_type ,
226 typename traits::array_layout ,
227 typename traits::device_type ,
228 typename traits::memory_traits >
232 typedef OffsetView<
typename traits::const_data_type ,
233 typename traits::array_layout ,
234 typename traits::device_type ,
235 typename traits::memory_traits >
239 typedef OffsetView<
typename traits::non_const_data_type ,
240 typename traits::array_layout ,
241 typename traits::device_type ,
242 typename traits::memory_traits >
246 typedef OffsetView<
typename traits::non_const_data_type ,
247 typename traits::array_layout ,
248 typename traits::host_mirror_space >
260 template<
typename iType >
261 KOKKOS_INLINE_FUNCTION constexpr
262 typename std::enable_if< std::is_integral<iType>::value ,
size_t >::type
263 extent(
const iType & r )
const
264 {
return m_map.extent(r); }
266 template<
typename iType >
267 KOKKOS_INLINE_FUNCTION constexpr
268 typename std::enable_if< std::is_integral<iType>::value ,
int >::type
269 extent_int(
const iType & r )
const
270 {
return static_cast<int>(m_map.extent(r)); }
272 KOKKOS_INLINE_FUNCTION constexpr
273 typename traits::array_layout layout()
const
274 {
return m_map.layout(); }
277 KOKKOS_INLINE_FUNCTION constexpr
size_t size()
const {
return m_map.dimension_0() *
278 m_map.dimension_1() *
279 m_map.dimension_2() *
280 m_map.dimension_3() *
281 m_map.dimension_4() *
282 m_map.dimension_5() *
283 m_map.dimension_6() *
284 m_map.dimension_7(); }
286 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_0()
const {
return m_map.stride_0(); }
287 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_1()
const {
return m_map.stride_1(); }
288 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_2()
const {
return m_map.stride_2(); }
289 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_3()
const {
return m_map.stride_3(); }
290 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_4()
const {
return m_map.stride_4(); }
291 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_5()
const {
return m_map.stride_5(); }
292 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_6()
const {
return m_map.stride_6(); }
293 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_7()
const {
return m_map.stride_7(); }
295 template<
typename iType >
296 KOKKOS_INLINE_FUNCTION constexpr
297 typename std::enable_if< std::is_integral<iType>::value ,
size_t >::type
298 stride(iType r)
const {
299 return (r == 0 ? m_map.stride_0() :
300 (r == 1 ? m_map.stride_1() :
301 (r == 2 ? m_map.stride_2() :
302 (r == 3 ? m_map.stride_3() :
303 (r == 4 ? m_map.stride_4() :
304 (r == 5 ? m_map.stride_5() :
305 (r == 6 ? m_map.stride_6() :
306 m_map.stride_7())))))));
309 template<
typename iType >
310 KOKKOS_INLINE_FUNCTION
void stride( iType *
const s )
const { m_map.stride(s); }
315 typedef typename map_type::reference_type reference_type ;
316 typedef typename map_type::pointer_type pointer_type ;
318 enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
320 KOKKOS_INLINE_FUNCTION constexpr
size_t span()
const {
return m_map.span(); }
321 KOKKOS_INLINE_FUNCTION
bool span_is_contiguous()
const {
return m_map.span_is_contiguous(); }
322 KOKKOS_INLINE_FUNCTION constexpr pointer_type data()
const {
return m_map.data(); }
327 KOKKOS_INLINE_FUNCTION
328 const Kokkos::Impl::ViewMapping< traits , void > &
329 implementation_map()
const {
return m_map ; }
336 is_layout_left = std::is_same<
typename traits::array_layout
339 is_layout_right = std::is_same<
typename traits::array_layout
342 is_layout_stride = std::is_same<
typename traits::array_layout
346 std::is_same< typename traits::specialize , void >::value &&
347 ( is_layout_left || is_layout_right || is_layout_stride )
350 template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible >
struct verify_space
351 { KOKKOS_FORCEINLINE_FUNCTION
static void check() {} };
353 template<
class Space >
struct verify_space<Space,false>
354 { KOKKOS_FORCEINLINE_FUNCTION
static void check()
355 { Kokkos::abort(
"Kokkos::View ERROR: attempt to access inaccessible memory space");
359 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
361 #define KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( ARG ) \
362 OffsetView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check(); \
363 Kokkos::Experimental::Impl::offsetview_verify_operator_bounds< typename traits::memory_space > ARG ;
367 #define KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( ARG ) \
368 OffsetView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
376 KOKKOS_FORCEINLINE_FUNCTION
380 return m_map.reference();
386 template<
typename I0>
387 KOKKOS_FORCEINLINE_FUNCTION
388 typename std::enable_if<
389 ( Kokkos::Impl::are_integral<I0>::value
392 ), reference_type >::type
393 operator()(
const I0 & i0)
const
396 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
397 const
size_t j0 = i0 - m_begins[0];
398 return m_map.reference(j0);
401 template< typename I0>
402 KOKKOS_FORCEINLINE_FUNCTION
403 typename std::enable_if<
404 ( Kokkos::Impl::are_integral<I0>::value
407 && ! is_layout_stride
408 ), reference_type >::type
409 operator()( const I0 & i0 )
const
411 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
412 const
size_t j0 = i0 - m_begins[0];
413 return m_map.m_impl_handle[ j0 ];
416 template< typename I0 >
417 KOKKOS_FORCEINLINE_FUNCTION
418 typename std::enable_if<
419 ( Kokkos::Impl::are_integral<I0>::value
423 ), reference_type >::type
424 operator()( const I0 & i0)
const
426 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
427 const
size_t j0 = i0 - m_begins[0];
428 return m_map.m_impl_handle[ m_map.m_impl_offset.m_stride.S0 * j0 ];
433 template< typename I0 >
434 KOKKOS_FORCEINLINE_FUNCTION
435 typename std::enable_if<
436 ( Kokkos::Impl::are_integral<I0>::value
439 ), reference_type >::type
440 operator[]( const I0 & i0 )
const
442 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
443 const
size_t j0 = i0 - m_begins[0];
444 return m_map.reference(j0);
447 template< typename I0 >
448 KOKKOS_FORCEINLINE_FUNCTION
449 typename std::enable_if<
450 ( Kokkos::Impl::are_integral<I0>::value
453 && ! is_layout_stride
454 ), reference_type >::type
455 operator[]( const I0 & i0 )
const
457 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
458 const
size_t j0 = i0 - m_begins[0];
459 return m_map.m_impl_handle[ j0 ];
462 template< typename I0 >
463 KOKKOS_FORCEINLINE_FUNCTION
464 typename std::enable_if<
465 ( Kokkos::Impl::are_integral<I0>::value
469 ), reference_type >::type
470 operator[]( const I0 & i0 )
const
472 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
473 const
size_t j0 = i0 - m_begins[0];
474 return m_map.m_impl_handle[ m_map.m_impl_offset.m_stride.S0 * j0 ];
481 template< typename I0 , typename I1 >
482 KOKKOS_FORCEINLINE_FUNCTION
483 typename std::enable_if<
484 ( Kokkos::Impl::are_integral<I0,I1>::value
487 ), reference_type >::type
488 operator()( const I0 & i0 , const I1 & i1)
const
490 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
491 const
size_t j0 = i0 - m_begins[0];
492 const
size_t j1 = i1 - m_begins[1];
493 return m_map.reference(j0,j1);
496 template< typename I0 , typename I1 >
497 KOKKOS_FORCEINLINE_FUNCTION
498 typename std::enable_if<
499 ( Kokkos::Impl::are_integral<I0,I1>::value
502 && is_layout_left && ( traits::rank_dynamic == 0 )
503 ), reference_type >::type
504 operator()( const I0 & i0 , const I1 & i1)
const
506 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
507 const
size_t j0 = i0 - m_begins[0];
508 const
size_t j1 = i1 - m_begins[1];
509 return m_map.m_impl_handle[ j0 + m_map.m_impl_offset.m_dim.N0 * j1 ];
512 template< typename I0 , typename I1>
513 KOKKOS_FORCEINLINE_FUNCTION
514 typename std::enable_if<
515 ( Kokkos::Impl::are_integral<I0,I1>::value
518 && is_layout_left && ( traits::rank_dynamic != 0 )
519 ), reference_type >::type
520 operator()( const I0 & i0 , const I1 & i1)
const
522 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
523 const
size_t j0 = i0 - m_begins[0];
524 const
size_t j1 = i1 - m_begins[1];
525 return m_map.m_impl_handle[ j0 + m_map.m_impl_offset.m_stride * j1 ];
528 template< typename I0 , typename I1 >
529 KOKKOS_FORCEINLINE_FUNCTION
530 typename std::enable_if<
531 ( Kokkos::Impl::are_integral<I0,I1>::value
534 && is_layout_right && ( traits::rank_dynamic == 0 )
535 ), reference_type >::type
536 operator()( const I0 & i0 , const I1 & i1 )
const
538 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
539 const
size_t j0 = i0 - m_begins[0];
540 const
size_t j1 = i1 - m_begins[1];
541 return m_map.m_impl_handle[ j1 + m_map.m_impl_offset.m_dim.N1 * j0 ];
544 template< typename I0 , typename I1 >
545 KOKKOS_FORCEINLINE_FUNCTION
546 typename std::enable_if<
547 ( Kokkos::Impl::are_integral<I0,I1>::value
550 && is_layout_right && ( traits::rank_dynamic != 0 )
551 ), reference_type >::type
552 operator()( const I0 & i0 , const I1 & i1 )
const
554 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
555 const
size_t j0 = i0 - m_begins[0];
556 const
size_t j1 = i1 - m_begins[1];
557 return m_map.m_impl_handle[ j1 + m_map.m_impl_offset.m_stride * j0 ];
560 template< typename I0 , typename I1>
561 KOKKOS_FORCEINLINE_FUNCTION
562 typename std::enable_if<
563 ( Kokkos::Impl::are_integral<I0,I1>::value
567 ), reference_type >::type
568 operator()( const I0 & i0 , const I1 & i1 )
const
570 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
571 const
size_t j0 = i0 - m_begins[0];
572 const
size_t j1 = i1 - m_begins[1];
573 return m_map.m_impl_handle[ j0 * m_map.m_impl_offset.m_stride.S0 +
574 j1 * m_map.m_impl_offset.m_stride.S1 ];
580 template< typename I0 , typename I1 , typename I2 >
581 KOKKOS_FORCEINLINE_FUNCTION
582 typename std::enable_if<
583 ( Kokkos::Impl::are_integral<I0,I1,I2>::value
586 ), reference_type >::type
587 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2)
const
589 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2) )
590 const
size_t j0 = i0 - m_begins[0];
591 const
size_t j1 = i1 - m_begins[1];
592 const
size_t j2 = i2 - m_begins[2];
593 return m_map.m_impl_handle[ m_map.m_impl_offset(j0, j1, j2) ];
596 template< typename I0 , typename I1 , typename I2>
597 KOKKOS_FORCEINLINE_FUNCTION
598 typename std::enable_if<
599 ( Kokkos::Impl::are_integral<I0,I1,I2>::value
602 ), reference_type >::type
603 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2)
const
605 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2) )
606 const
size_t j0 = i0 - m_begins[0];
607 const
size_t j1 = i1 - m_begins[1];
608 const
size_t j2 = i2 - m_begins[2];
609 return m_map.reference(j0, j1, j2);
615 template< typename I0 , typename I1 , typename I2 , typename I3>
616 KOKKOS_FORCEINLINE_FUNCTION
617 typename std::enable_if<
618 ( Kokkos::Impl::are_integral<I0,I1,I2,I3>::value
621 ), reference_type >::type
622 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3)
const
624 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3) )
625 const
size_t j0 = i0 - m_begins[0];
626 const
size_t j1 = i1 - m_begins[1];
627 const
size_t j2 = i2 - m_begins[2];
628 const
size_t j3 = i3 - m_begins[3];
629 return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3) ];
632 template< typename I0 , typename I1 , typename I2 , typename I3 >
633 KOKKOS_FORCEINLINE_FUNCTION
634 typename std::enable_if<
635 ( Kokkos::Impl::are_integral<I0,I1,I2,I3>::value
638 ), reference_type >::type
639 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3)
const
641 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3) )
642 const
size_t j0 = i0 - m_begins[0];
643 const
size_t j1 = i1 - m_begins[1];
644 const
size_t j2 = i2 - m_begins[2];
645 const
size_t j3 = i3 - m_begins[3];
646 return m_map.reference(j0,j1,j2,j3);
652 template< typename I0 , typename I1 , typename I2 , typename I3
654 KOKKOS_FORCEINLINE_FUNCTION
655 typename std::enable_if<
656 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4>::value
659 ), reference_type >::type
660 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
661 , const I4 & i4 )
const
663 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3, i4) )
664 const
size_t j0 = i0 - m_begins[0];
665 const
size_t j1 = i1 - m_begins[1];
666 const
size_t j2 = i2 - m_begins[2];
667 const
size_t j3 = i3 - m_begins[3];
668 const
size_t j4 = i4 - m_begins[4];
669 return m_map.m_impl_handle[ m_map.m_impl_offset(j0, j1,j2, j3, j4) ];
672 template< typename I0 , typename I1 , typename I2 , typename I3
674 KOKKOS_FORCEINLINE_FUNCTION
675 typename std::enable_if<
676 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4>::value
679 ), reference_type >::type
680 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
681 , const I4 & i4)
const
683 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3, i4) )
684 const
size_t j0 = i0 - m_begins[0];
685 const
size_t j1 = i1 - m_begins[1];
686 const
size_t j2 = i2 - m_begins[2];
687 const
size_t j3 = i3 - m_begins[3];
688 const
size_t j4 = i4 - m_begins[4];
689 return m_map.reference(j0,j1,j2,j3,j4);
695 template< typename I0 , typename I1 , typename I2 , typename I3
696 , typename I4 , typename I5 >
697 KOKKOS_FORCEINLINE_FUNCTION
698 typename std::enable_if<
699 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5>::value
702 ), reference_type >::type
703 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
704 , const I4 & i4 , const I5 & i5 )
const
706 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5) )
707 const
size_t j0 = i0 - m_begins[0];
708 const
size_t j1 = i1 - m_begins[1];
709 const
size_t j2 = i2 - m_begins[2];
710 const
size_t j3 = i3 - m_begins[3];
711 const
size_t j4 = i4 - m_begins[4];
712 const
size_t j5 = i5 - m_begins[5];
713 return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3,j4,j5) ];
716 template< typename I0 , typename I1 , typename I2 , typename I3
717 , typename I4 , typename I5>
718 KOKKOS_FORCEINLINE_FUNCTION
719 typename std::enable_if<
720 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5>::value
723 ), reference_type >::type
724 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
725 , const I4 & i4 , const I5 & i5)
const
727 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5) )
728 const
size_t j0 = i0 - m_begins[0];
729 const
size_t j1 = i1 - m_begins[1];
730 const
size_t j2 = i2 - m_begins[2];
731 const
size_t j3 = i3 - m_begins[3];
732 const
size_t j4 = i4 - m_begins[4];
733 const
size_t j5 = i5 - m_begins[5];
734 return m_map.reference(j0,j1,j2,j3,j4,j5);
740 template< typename I0 , typename I1 , typename I2 , typename I3
741 , typename I4 , typename I5 , typename I6>
742 KOKKOS_FORCEINLINE_FUNCTION
743 typename std::enable_if<
744 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6>::value
747 ), reference_type >::type
748 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
749 , const I4 & i4 , const I5 & i5 , const I6 & i6)
const
751 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6) )
752 const
size_t j0 = i0 - m_begins[0];
753 const
size_t j1 = i1 - m_begins[1];
754 const
size_t j2 = i2 - m_begins[2];
755 const
size_t j3 = i3 - m_begins[3];
756 const
size_t j4 = i4 - m_begins[4];
757 const
size_t j5 = i5 - m_begins[5];
758 const
size_t j6 = i6 - m_begins[6];
759 return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3,j4,j5,j6) ];
762 template< typename I0 , typename I1 , typename I2 , typename I3
763 , typename I4 , typename I5 , typename I6 >
764 KOKKOS_FORCEINLINE_FUNCTION
765 typename std::enable_if<
766 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6>::value
769 ), reference_type >::type
770 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
771 , const I4 & i4 , const I5 & i5 , const I6 & i6)
const
773 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6) )
774 const
size_t j0 = i0 - m_begins[0];
775 const
size_t j1 = i1 - m_begins[1];
776 const
size_t j2 = i2 - m_begins[2];
777 const
size_t j3 = i3 - m_begins[3];
778 const
size_t j4 = i4 - m_begins[4];
779 const
size_t j5 = i5 - m_begins[5];
780 const
size_t j6 = i6 - m_begins[6];
781 return m_map.reference(j0,j1,j2,j3,j4,j5,j6);
787 template< typename I0 , typename I1 , typename I2 , typename I3
788 , typename I4 , typename I5 , typename I6 , typename I7 >
789 KOKKOS_FORCEINLINE_FUNCTION
790 typename std::enable_if<
791 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6,I7>::value
794 ), reference_type >::type
795 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
796 , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7)
const
798 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6, i7) )
799 const
size_t j0 = i0 - m_begins[0];
800 const
size_t j1 = i1 - m_begins[1];
801 const
size_t j2 = i2 - m_begins[2];
802 const
size_t j3 = i3 - m_begins[3];
803 const
size_t j4 = i4 - m_begins[4];
804 const
size_t j5 = i5 - m_begins[5];
805 const
size_t j6 = i6 - m_begins[6];
806 const
size_t j7 = i7 - m_begins[7];
807 return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3,j4,j5,j6,j7) ];
810 template< typename I0 , typename I1 , typename I2 , typename I3
811 , typename I4 , typename I5 , typename I6 , typename I7>
812 KOKKOS_FORCEINLINE_FUNCTION
813 typename std::enable_if<
814 ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6,I7>::value
817 ), reference_type >::type
818 operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
819 , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7 )
const
821 KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6, i7) )
822 const
size_t j0 = i0 - m_begins[0];
823 const
size_t j1 = i1 - m_begins[1];
824 const
size_t j2 = i2 - m_begins[2];
825 const
size_t j3 = i3 - m_begins[3];
826 const
size_t j4 = i4 - m_begins[4];
827 const
size_t j5 = i5 - m_begins[5];
828 const
size_t j6 = i6 - m_begins[6];
829 const
size_t j7 = i7 - m_begins[7];
830 return m_map.reference(j0,j1,j2,j3,j4,j5,j6,j7);
834 #undef KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY
839 KOKKOS_INLINE_FUNCTION
842 KOKKOS_INLINE_FUNCTION
843 OffsetView() : m_track(), m_map() {
845 for(
size_t i = 0; i < Rank; ++i) m_begins[i] = KOKKOS_INVALID_INDEX;
848 KOKKOS_INLINE_FUNCTION
849 OffsetView(
const OffsetView & rhs ) : m_track( rhs.m_track, traits::is_managed ), m_map( rhs.m_map ),
850 m_begins(rhs.m_begins) {}
852 KOKKOS_INLINE_FUNCTION
853 OffsetView( OffsetView && rhs ) : m_track( std::move(rhs.m_track) ),
854 m_map( std::move(rhs.m_map)), m_begins(std::move(rhs.m_begins)) {}
856 KOKKOS_INLINE_FUNCTION
857 OffsetView & operator = (
const OffsetView & rhs ) {
858 m_track = rhs.m_track ;
860 m_begins = rhs.m_begins;
864 KOKKOS_INLINE_FUNCTION
865 OffsetView & operator = ( OffsetView && rhs ) {
866 m_track = std::move(rhs.m_track) ;
867 m_map = std::move(rhs.m_map) ;
868 m_begins = std::move(rhs.m_begins) ;
874 typedef View<
typename traits::scalar_array_type ,
875 typename traits::array_layout ,
876 typename traits::device_type ,
877 typename traits::memory_traits > view_type;
880 KOKKOS_INLINE_FUNCTION
881 view_type view()
const {
883 view_type v(m_track, m_map);
887 template<
class RT,
class ... RP>
888 KOKKOS_INLINE_FUNCTION
889 OffsetView(
const View<RT, RP...> & aview) :
890 m_track(aview.impl_track()), m_map(){
892 typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
893 typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
894 static_assert( Mapping::is_assignable ,
"Incompatible OffsetView copy construction" );
895 Mapping::assign( m_map , aview.impl_map() , m_track );
897 for (
int i = 0; i < aview.Rank; ++i) {
902 template<
class RT,
class ... RP>
903 KOKKOS_INLINE_FUNCTION
904 OffsetView(
const View<RT, RP...> & aview
905 ,
const index_list_type & minIndices) :
906 m_track(aview.impl_track()), m_map(){
908 typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
909 typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
910 static_assert( Mapping::is_assignable ,
"Incompatible OffsetView copy construction" );
911 Mapping::assign( m_map , aview.impl_map() , m_track );
913 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
914 Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
916 Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
920 for (
size_t i = 0; i < minIndices.size(); ++i) {
921 m_begins[i] = minIndices.begin()[i];
924 template<
class RT,
class ... RP>
925 KOKKOS_INLINE_FUNCTION
926 OffsetView(
const View<RT, RP...> & aview
927 ,
const begins_type & beg) :
928 m_track(aview.impl_track()), m_map(), m_begins(beg){
930 typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
931 typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
932 static_assert( Mapping::is_assignable ,
"Incompatible OffsetView copy construction" );
933 Mapping::assign( m_map , aview.impl_map() , m_track );
948 template<
class RT ,
class ... RP >
949 KOKKOS_INLINE_FUNCTION
950 OffsetView(
const OffsetView<RT,RP...> & rhs )
951 : m_track( rhs.m_track , traits::is_managed )
953 , m_begins(rhs.m_begins)
955 typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
956 typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
957 static_assert( Mapping::is_assignable ,
"Incompatible OffsetView copy construction" );
958 Mapping::assign( m_map , rhs.m_map , rhs.m_track );
964 KOKKOS_INLINE_FUNCTION
965 int use_count()
const
966 {
return m_track.use_count(); }
969 const std::string label()
const
970 {
return m_track.template get_label< typename traits::memory_space >(); }
973 template<
typename Label>
975 OffsetView(
const Label & arg_label
976 ,
typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value ,
const index_list_type >::type
978 ,
const index_list_type range1 = KOKKOS_INVALID_INDEX_RANGE
979 ,
const index_list_type range2 = KOKKOS_INVALID_INDEX_RANGE
980 ,
const index_list_type range3 = KOKKOS_INVALID_INDEX_RANGE
981 ,
const index_list_type range4 = KOKKOS_INVALID_INDEX_RANGE
982 ,
const index_list_type range5 = KOKKOS_INVALID_INDEX_RANGE
983 ,
const index_list_type range6 = KOKKOS_INVALID_INDEX_RANGE
984 ,
const index_list_type range7 = KOKKOS_INVALID_INDEX_RANGE
986 ) : OffsetView( Kokkos::Impl::ViewCtorProp< std::string >( arg_label ),
987 typename traits::array_layout
988 ( range0.begin()[1] - range0.begin()[0] + 1, range1.begin()[1] - range1.begin()[0] + 1 ,
989 range2.begin()[1] - range2.begin()[0] + 1, range3.begin()[1] - range3.begin()[0] + 1,
990 range4.begin()[1] - range4.begin()[0] + 1, range5.begin()[1] - range5.begin()[0] + 1 ,
991 range6.begin()[1] - range6.begin()[0] + 1, range7.begin()[1] - range7.begin()[0] + 1 ),
992 {range0.begin()[0], range1.begin()[0], range2.begin()[0], range3.begin()[0], range4.begin()[0],
993 range5.begin()[0], range6.begin()[0], range7.begin()[0] })
1000 template<
class ... P >
1001 explicit KOKKOS_INLINE_FUNCTION
1002 OffsetView(
const Kokkos::Impl::ViewCtorProp< P ... > & arg_prop
1003 ,
typename std::enable_if< Kokkos::Impl::ViewCtorProp< P... >::has_pointer ,
typename traits::array_layout >::type
const & arg_layout
1004 ,
const index_list_type minIndices
1007 , m_map( arg_prop , arg_layout )
1011 for (
size_t i = 0; i < minIndices.size(); ++i) {
1012 m_begins[i] = minIndices.begin()[i];
1015 std::is_same< pointer_type
1016 ,
typename Kokkos::Impl::ViewCtorProp< P... >::pointer_type
1018 "When constructing OffsetView to wrap user memory, you must supply matching pointer type" );
1021 template<
class ... P >
1023 OffsetView(
const Kokkos::Impl::ViewCtorProp< P ... > & arg_prop
1024 ,
typename std::enable_if< ! Kokkos::Impl::ViewCtorProp< P... >::has_pointer ,
typename traits::array_layout>::type
const & arg_layout
1025 ,
const index_list_type minIndices
1032 for(
size_t i = 0; i < Rank; ++i)
1033 m_begins[i] = minIndices.begin()[i];
1036 typedef Kokkos::Impl::ViewCtorProp< P ... > alloc_prop_input ;
1040 typedef Kokkos::Impl::ViewCtorProp
1041 < P ...,
typename std::conditional < alloc_prop_input::has_label
1042 , std::integral_constant<unsigned,0>,
typename std::string >::type
1043 ,
typename std::conditional
1044 < alloc_prop_input::has_memory_space
1045 , std::integral_constant<unsigned,1>
1046 ,
typename traits::device_type::memory_space
1048 ,
typename std::conditional
1049 < alloc_prop_input::has_execution_space
1050 , std::integral_constant<unsigned,2>
1051 ,
typename traits::device_type::execution_space
1055 static_assert( traits::is_managed
1056 ,
"OffsetView allocation constructor requires managed memory" );
1058 if ( alloc_prop::initialize &&
1059 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
1060 ! alloc_prop::execution_space::is_initialized()
1062 ! alloc_prop::execution_space::impl_is_initialized()
1067 Kokkos::Impl::throw_runtime_exception(
"Constructing OffsetView and initializing data with uninitialized execution space");
1071 alloc_prop prop( arg_prop );
1074 #if defined( KOKKOS_ENABLE_CUDA )
1080 if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
1081 traits::device_type::memory_space::execution_space::fence();
1086 Kokkos::Impl::SharedAllocationRecord<> *
1087 record = m_map.allocate_shared( prop , arg_layout );
1090 #if defined( KOKKOS_ENABLE_CUDA )
1091 if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
1092 traits::device_type::memory_space::execution_space::fence();
1098 m_track.assign_allocated_record_to_uninitialized( record );
1100 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
1101 Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
1103 Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
1118 template <
typename D ,
class ... P >
1119 KOKKOS_INLINE_FUNCTION
1120 constexpr
unsigned rank(
const OffsetView<D , P...> & V ) {
return V.Rank; }
1127 KOKKOS_INLINE_FUNCTION
1128 typename std::enable_if< std::is_integral<T>::value, T>::type
1129 shift_input(
const T arg,
const int64_t offset)
1131 return arg - offset;
1134 KOKKOS_INLINE_FUNCTION
1136 shift_input(
const Kokkos::Impl::ALL_t arg,
const int64_t offset)
1142 KOKKOS_INLINE_FUNCTION
1147 return Kokkos::make_pair<T,T>(arg.
first - offset, arg.
second - offset);
1152 typename std::enable_if< std::is_integral<T>::value, std::pair<T,T> >::type
1153 shift_input(
const std::pair<T, T> arg,
const int64_t offset)
1156 return std::make_pair<T,T>(arg.first - offset, arg.second - offset);
1160 template <
size_t N,
class Arg,
class A>
1161 KOKKOS_INLINE_FUNCTION
1163 map_arg_to_new_begin(
const size_t i,
1165 const Arg arg,
const A viewBegins,
size_t & counter) {
1167 if( !std::is_integral<Arg>::value) {
1168 subviewBegins[counter] = shiftedArg == arg ? viewBegins[i] : 0;
1173 template <
size_t N,
class Arg,
class A>
1174 KOKKOS_INLINE_FUNCTION
1176 map_arg_to_new_begin(
const size_t i,
1178 const Arg arg,
const A viewBegins,
size_t & counter) {
1183 template<
class D,
class ... P ,
class T >
1184 KOKKOS_INLINE_FUNCTION
1185 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1187 , ViewTraits< D , P... >
1190 subview_offset(
const OffsetView< D, P... > & src, T arg) {
1192 auto theView = src.view();
1193 auto begins = src.begins();
1195 T shiftedArg = shift_input(arg, begins[0]);
1197 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1199 , ViewTraits< D , P... >
1202 auto theSubview = Kokkos::subview( theView , shiftedArg);
1206 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg, arg, begins, counter);
1208 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1210 , ViewTraits< D , P... > , T >::type >::type offsetView(theSubview, subviewBegins);
1216 template<
class D,
class ... P ,
class T0,
class T1 >
1217 KOKKOS_INLINE_FUNCTION
1218 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1220 , ViewTraits< D , P... >
1223 subview_offset(
const Kokkos::Experimental::OffsetView< D, P... > & src, T0 arg0, T1 arg1) {
1225 auto theView = src.view();
1226 auto begins = src.begins();
1228 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1229 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1231 auto theSubview = Kokkos::subview(theView , shiftedArg0, shiftedArg1);
1232 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1234 , ViewTraits< D , P... >
1235 , T0, T1>::type::Rank;
1239 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1240 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1242 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1244 , ViewTraits< D , P... > , T0, T1 >::type >::type offsetView(theSubview, subviewBegins);
1250 template<
class D,
class ... P ,
class T0,
class T1,
class T2 >
1251 KOKKOS_INLINE_FUNCTION
1252 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1254 , ViewTraits< D , P... >
1257 subview_offset(
const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2) {
1259 auto theView = src.view();
1260 auto begins = src.begins();
1262 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1263 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1264 T2 shiftedArg2 = shift_input(arg2, begins[2]);
1266 auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2);
1268 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1270 , ViewTraits< D , P... >
1271 , T0, T1, T2>::type::Rank;
1276 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1277 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1278 Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1280 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1282 , ViewTraits< D , P... > , T0, T1, T2 >::type >::type offsetView(theSubview, subviewBegins);
1287 template<
class D,
class ... P ,
class T0,
class T1,
class T2,
class T3 >
1288 KOKKOS_INLINE_FUNCTION
1289 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1291 , ViewTraits< D , P... >
1294 subview_offset(
const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
1296 auto theView = src.view();
1297 auto begins = src.begins();
1299 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1300 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1301 T2 shiftedArg2 = shift_input(arg2, begins[2]);
1302 T3 shiftedArg3 = shift_input(arg3, begins[3]);
1304 auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3);
1306 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1308 , ViewTraits< D , P... >
1309 , T0, T1, T2, T3>::type::Rank;
1313 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1314 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1315 Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1316 Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1318 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1320 , ViewTraits< D , P... > , T0, T1, T2, T3 >::type >::type offsetView(theSubview, subviewBegins);
1325 template<
class D,
class ... P ,
class T0,
class T1,
class T2,
class T3,
class T4 >
1326 KOKKOS_INLINE_FUNCTION
1327 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1329 , ViewTraits< D , P... >
1330 , T0, T1, T2, T3, T4
1332 subview_offset(
const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
1334 auto theView = src.view();
1335 auto begins = src.begins();
1337 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1338 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1339 T2 shiftedArg2 = shift_input(arg2, begins[2]);
1340 T3 shiftedArg3 = shift_input(arg3, begins[3]);
1341 T4 shiftedArg4 = shift_input(arg4, begins[4]);
1343 auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4);
1345 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1347 , ViewTraits< D , P... >
1348 , T0, T1, T2, T3, T4>::type::Rank;
1352 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1353 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1354 Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1355 Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1356 Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1358 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1360 , ViewTraits< D , P... > , T0, T1, T2, T3, T4 >::type >::type offsetView(theSubview, subviewBegins);
1365 template<
class D,
class ... P ,
class T0,
class T1,
class T2,
class T3,
class T4,
1367 KOKKOS_INLINE_FUNCTION
1368 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1370 , ViewTraits< D , P... >
1371 , T0, T1, T2, T3, T4, T5
1373 subview_offset(
const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
1375 auto theView = src.view();
1376 auto begins = src.begins();
1378 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1379 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1380 T2 shiftedArg2 = shift_input(arg2, begins[2]);
1381 T3 shiftedArg3 = shift_input(arg3, begins[3]);
1382 T4 shiftedArg4 = shift_input(arg4, begins[4]);
1383 T5 shiftedArg5 = shift_input(arg5, begins[5]);
1385 auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5);
1387 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1389 , ViewTraits< D , P... >
1390 , T0, T1, T2, T3, T4, T5>::type::Rank;
1395 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1396 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1397 Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1398 Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1399 Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1400 Kokkos::Experimental::Impl::map_arg_to_new_begin(5, subviewBegins, shiftedArg5, arg5, begins, counter);
1402 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1404 , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5 >::type >::type offsetView(theSubview, subviewBegins);
1408 template<
class D,
class ... P ,
class T0,
class T1,
class T2,
class T3,
class T4,
1410 KOKKOS_INLINE_FUNCTION
1411 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1413 , ViewTraits< D , P... >
1414 , T0, T1, T2, T3, T4, T5, T6
1416 subview_offset(
const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
1419 auto theView = src.view();
1420 auto begins = src.begins();
1422 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1423 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1424 T2 shiftedArg2 = shift_input(arg2, begins[2]);
1425 T3 shiftedArg3 = shift_input(arg3, begins[3]);
1426 T4 shiftedArg4 = shift_input(arg4, begins[4]);
1427 T5 shiftedArg5 = shift_input(arg5, begins[5]);
1428 T6 shiftedArg6 = shift_input(arg6, begins[6]);
1430 auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5,
1433 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1435 , ViewTraits< D , P... >
1436 , T0, T1, T2, T3, T4, T5, T6>::type::Rank;
1441 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1442 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1443 Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1444 Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1445 Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1446 Kokkos::Experimental::Impl::map_arg_to_new_begin(5, subviewBegins, shiftedArg5, arg5, begins, counter);
1447 Kokkos::Experimental::Impl::map_arg_to_new_begin(6, subviewBegins, shiftedArg6, arg6, begins, counter);
1449 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1451 , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5,
1452 T6 >::type >::type offsetView(theSubview, subviewBegins);
1457 template<
class D,
class ... P ,
class T0,
class T1,
class T2,
class T3,
class T4,
1458 class T5,
class T6,
class T7>
1459 KOKKOS_INLINE_FUNCTION
1460 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1462 , ViewTraits< D , P... >
1463 , T0, T1, T2, T3, T4, T5, T6, T7
1465 subview_offset(
const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
1468 auto theView = src.view();
1469 auto begins = src.begins();
1471 T0 shiftedArg0 = shift_input(arg0, begins[0]);
1472 T1 shiftedArg1 = shift_input(arg1, begins[1]);
1473 T2 shiftedArg2 = shift_input(arg2, begins[2]);
1474 T3 shiftedArg3 = shift_input(arg3, begins[3]);
1475 T4 shiftedArg4 = shift_input(arg4, begins[4]);
1476 T5 shiftedArg5 = shift_input(arg5, begins[5]);
1477 T6 shiftedArg6 = shift_input(arg6, begins[6]);
1478 T7 shiftedArg7 = shift_input(arg7, begins[7]);
1480 auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5,
1481 shiftedArg6, shiftedArg7);
1483 constexpr
size_t rank = Kokkos::Impl::ViewMapping
1485 , ViewTraits< D , P... >
1486 , T0, T1, T2, T3, T4, T5, T6, T7>::type::Rank;
1491 Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1492 Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1493 Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1494 Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1495 Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1496 Kokkos::Experimental::Impl::map_arg_to_new_begin(5, subviewBegins, shiftedArg5, arg5, begins, counter);
1497 Kokkos::Experimental::Impl::map_arg_to_new_begin(6, subviewBegins, shiftedArg6, arg6, begins, counter);
1498 Kokkos::Experimental::Impl::map_arg_to_new_begin(7, subviewBegins, shiftedArg7, arg7, begins, counter);
1500 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping<
1502 , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5,
1503 T6, T7 >::type >::type offsetView(theSubview, subviewBegins);
1509 template<
class D,
class ... P ,
class ... Args >
1510 KOKKOS_INLINE_FUNCTION
1511 typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<
typename Kokkos::Impl::ViewMapping
1513 , ViewTraits< D , P... >
1516 subview(
const OffsetView< D, P... > & src , Args ... args )
1518 static_assert( OffsetView< D , P... >::Rank ==
sizeof...(Args) ,
1519 "subview requires one argument for each source OffsetView rank" );
1522 return Kokkos::Experimental::Impl::subview_offset(src, args...);
1533 namespace Experimental {
1534 template<
class LT ,
class ... LP ,
class RT ,
class ... RP >
1535 KOKKOS_INLINE_FUNCTION
1536 bool operator == (
const OffsetView<LT,LP...> & lhs ,
1537 const OffsetView<RT,RP...> & rhs )
1540 typedef ViewTraits<LT,LP...> lhs_traits ;
1541 typedef ViewTraits<RT,RP...> rhs_traits ;
1544 std::is_same<
typename lhs_traits::const_value_type ,
1545 typename rhs_traits::const_value_type >::value &&
1546 std::is_same<
typename lhs_traits::array_layout ,
1547 typename rhs_traits::array_layout >::value &&
1548 std::is_same<
typename lhs_traits::memory_space ,
1549 typename rhs_traits::memory_space >::value &&
1550 unsigned(lhs_traits::rank) == unsigned(rhs_traits::rank) &&
1551 lhs.data() == rhs.data() &&
1552 lhs.span() == rhs.span() &&
1553 lhs.extent(0) == rhs.extent(0) &&
1554 lhs.extent(1) == rhs.extent(1) &&
1555 lhs.extent(2) == rhs.extent(2) &&
1556 lhs.extent(3) == rhs.extent(3) &&
1557 lhs.extent(4) == rhs.extent(4) &&
1558 lhs.extent(5) == rhs.extent(5) &&
1559 lhs.extent(6) == rhs.extent(6) &&
1560 lhs.extent(7) == rhs.extent(7) &&
1561 lhs.begin(0) == rhs.begin(0) &&
1562 lhs.begin(1) == rhs.begin(1) &&
1563 lhs.begin(2) == rhs.begin(2) &&
1564 lhs.begin(3) == rhs.begin(3) &&
1565 lhs.begin(4) == rhs.begin(4) &&
1566 lhs.begin(5) == rhs.begin(5) &&
1567 lhs.begin(6) == rhs.begin(6) &&
1568 lhs.begin(7) == rhs.begin(7)
1572 template<
class LT ,
class ... LP ,
class RT ,
class ... RP >
1573 KOKKOS_INLINE_FUNCTION
1574 bool operator != (
const OffsetView<LT,LP...> & lhs ,
1575 const OffsetView<RT,RP...> & rhs )
1580 template<
class LT ,
class ... LP ,
class RT ,
class ... RP >
1581 KOKKOS_INLINE_FUNCTION
1583 const OffsetView<RT,RP...> & rhs )
1586 typedef ViewTraits<LT,LP...> lhs_traits ;
1587 typedef ViewTraits<RT,RP...> rhs_traits ;
1590 std::is_same<
typename lhs_traits::const_value_type ,
1591 typename rhs_traits::const_value_type >::value &&
1592 std::is_same<
typename lhs_traits::array_layout ,
1593 typename rhs_traits::array_layout >::value &&
1594 std::is_same<
typename lhs_traits::memory_space ,
1595 typename rhs_traits::memory_space >::value &&
1596 unsigned(lhs_traits::rank) == unsigned(rhs_traits::rank) &&
1597 lhs.data() == rhs.data() &&
1598 lhs.span() == rhs.span() &&
1599 lhs.extent(0) == rhs.extent(0) &&
1600 lhs.extent(1) == rhs.extent(1) &&
1601 lhs.extent(2) == rhs.extent(2) &&
1602 lhs.extent(3) == rhs.extent(3) &&
1603 lhs.extent(4) == rhs.extent(4) &&
1604 lhs.extent(5) == rhs.extent(5) &&
1605 lhs.extent(6) == rhs.extent(6) &&
1606 lhs.extent(7) == rhs.extent(7)
1610 template<
class LT ,
class ... LP ,
class RT ,
class ... RP >
1611 KOKKOS_INLINE_FUNCTION
1612 bool operator == (
const OffsetView<LT,LP...> & lhs ,
1613 const View<RT,RP...> & rhs )
1614 {
return rhs == lhs;}
1624 namespace Experimental {
1625 template<
class DT ,
class ... DP >
1628 (
const OffsetView<DT,DP...> & dst
1629 ,
typename ViewTraits<DT,DP...>::const_value_type & value
1630 ,
typename std::enable_if<
1631 std::is_same<
typename ViewTraits<DT,DP...>::specialize ,
void >::value
1635 std::is_same<
typename ViewTraits<DT,DP...>::non_const_value_type ,
1636 typename ViewTraits<DT,DP...>::value_type >::value
1637 ,
"deep_copy requires non-const type" );
1639 auto dstView = dst.view();
1644 template<
class DT ,
class ... DP ,
class ST ,
class ... SP >
1647 (
const OffsetView<DT,DP...> & dst
1648 ,
const OffsetView<ST,SP...> & value
1649 ,
typename std::enable_if<
1650 std::is_same<
typename ViewTraits<DT,DP...>::specialize ,
void >::value
1654 std::is_same<
typename ViewTraits<DT,DP...>::value_type ,
1655 typename ViewTraits<ST,SP...>::non_const_value_type >::value
1656 ,
"deep_copy requires matching non-const destination type" );
1658 auto dstView = dst.view();
1662 template<
class DT ,
class ... DP ,
class ST ,
class ... SP >
1665 (
const OffsetView<DT,DP...> & dst
1666 ,
const View<ST,SP...> & value
1667 ,
typename std::enable_if<
1668 std::is_same<
typename ViewTraits<DT,DP...>::specialize ,
void >::value
1672 std::is_same<
typename ViewTraits<DT,DP...>::value_type ,
1673 typename ViewTraits<ST,SP...>::non_const_value_type >::value
1674 ,
"deep_copy requires matching non-const destination type" );
1676 auto dstView = dst.view();
1681 template<
class DT ,
class ... DP ,
class ST ,
class ... SP >
1684 (
const View<DT,DP...> & dst
1685 ,
const OffsetView<ST,SP...> & value
1686 ,
typename std::enable_if<
1687 std::is_same<
typename ViewTraits<DT,DP...>::specialize ,
void >::value
1691 std::is_same<
typename ViewTraits<DT,DP...>::value_type ,
1692 typename ViewTraits<ST,SP...>::non_const_value_type >::value
1693 ,
"deep_copy requires matching non-const destination type" );
1701 template<
class Space,
class T,
class ... P>
1702 struct MirrorOffsetViewType {
1704 typedef typename Kokkos::Experimental::OffsetView<T,P...> src_view_type;
1706 typedef typename Space::memory_space memory_space;
1708 enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
1710 typedef typename src_view_type::array_layout array_layout;
1712 typedef typename src_view_type::non_const_data_type data_type;
1714 typedef Kokkos::Experimental::OffsetView<data_type,array_layout,Space> dest_view_type;
1717 typedef typename std::conditional<is_same_memspace,src_view_type,dest_view_type>::type view_type;
1720 template<
class Space,
class T,
class ... P>
1721 struct MirrorOffsetType {
1723 typedef typename Kokkos::Experimental::OffsetView<T,P...> src_view_type;
1725 typedef typename Space::memory_space memory_space;
1727 enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
1729 typedef typename src_view_type::array_layout array_layout;
1731 typedef typename src_view_type::non_const_data_type data_type;
1733 typedef Kokkos::Experimental::OffsetView<data_type,array_layout,Space> view_type;
1738 template<
class T ,
class ... P >
1740 typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror
1741 create_mirror(
const Kokkos::Experimental::OffsetView<T,P...> & src
1742 ,
typename std::enable_if<
1743 ! std::is_same<
typename Kokkos::ViewTraits<T,P...>::array_layout
1748 typedef OffsetView<T,P...> src_type ;
1749 typedef typename src_type::HostMirror dst_type ;
1751 return dst_type( Kokkos::Impl::ViewCtorProp< std::string >(std::string( src.label() ).append(
"_mirror") ),
1752 typename Kokkos::ViewTraits<T,P...>::array_layout
1753 ( src.extent(0), src.extent(1), src.extent(2), src.extent(3), src.extent(4),
1754 src.extent(5), src.extent(6), src.extent(7) ),
1755 { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1756 src.begin(5), src.begin(6), src.begin(7) });
1759 template<
class T ,
class ... P >
1761 typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror
1762 create_mirror(
const Kokkos::Experimental::OffsetView<T,P...> & src
1763 ,
typename std::enable_if<
1764 std::is_same<
typename Kokkos::ViewTraits<T,P...>::array_layout
1769 typedef OffsetView<T,P...> src_type ;
1770 typedef typename src_type::HostMirror dst_type ;
1774 layout.dimension[0] = src.extent(0);
1775 layout.dimension[1] = src.extent(1);
1776 layout.dimension[2] = src.extent(2);
1777 layout.dimension[3] = src.extent(3);
1778 layout.dimension[4] = src.extent(4);
1779 layout.dimension[5] = src.extent(5);
1780 layout.dimension[6] = src.extent(6);
1781 layout.dimension[7] = src.extent(7);
1783 layout.stride[0] = src.stride_0();
1784 layout.stride[1] = src.stride_1();
1785 layout.stride[2] = src.stride_2();
1786 layout.stride[3] = src.stride_3();
1787 layout.stride[4] = src.stride_4();
1788 layout.stride[5] = src.stride_5();
1789 layout.stride[6] = src.stride_6();
1790 layout.stride[7] = src.stride_7();
1792 return dst_type( std::string( src.label() ).append(
"_mirror") , layout,
1793 { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1794 src.begin(5), src.begin(6), src.begin(7) } );
1799 template<
class Space,
class T,
class ... P>
1800 typename Kokkos::Experimental::Impl::MirrorOffsetType<Space,T,P ...>::view_type
1801 create_mirror(
const Space& ,
const Kokkos::Experimental::OffsetView<T,P...> & src) {
1802 return typename Kokkos::Experimental::Impl::MirrorOffsetType<Space,T,P ...>::view_type(src.label(),src.layout(),
1803 { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1804 src.begin(5), src.begin(6), src.begin(7) } );
1808 template<
class T ,
class ... P >
1810 typename Kokkos::Experimental::OffsetView< T, P... >::HostMirror
1811 create_mirror_view(
const typename Kokkos::Experimental::OffsetView< T,P... > & src
1812 ,
typename std::enable_if<(
1813 std::is_same<
typename Kokkos::Experimental::OffsetView<T,P...>::memory_space
1814 ,
typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::memory_space
1817 std::is_same<
typename Kokkos::Experimental::OffsetView<T,P...>::data_type
1818 ,
typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::data_type
1826 template<
class T ,
class ... P >
1828 typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror
1829 create_mirror_view(
const Kokkos::Experimental::OffsetView<T,P...> & src
1830 ,
typename std::enable_if< ! (
1831 std::is_same<
typename Kokkos::Experimental::OffsetView<T,P...>::memory_space
1832 ,
typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::memory_space
1835 std::is_same<
typename Kokkos::Experimental::OffsetView<T,P...>::data_type
1836 ,
typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::data_type
1841 return Kokkos::Experimental::create_mirror( src );
1845 template<
class Space,
class T,
class ... P>
1846 typename Kokkos::Experimental::Impl::MirrorOffsetViewType<Space,T,P ...>::view_type
1847 create_mirror_view(
const Space& ,
const Kokkos::Experimental::OffsetView<T,P...> & src
1848 ,
typename std::enable_if<Impl::MirrorOffsetViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1853 template<
class Space,
class T,
class ... P>
1854 typename Kokkos::Experimental::Impl::MirrorOffsetViewType<Space,T,P ...>::view_type
1855 create_mirror_view(
const Space& ,
const Kokkos::Experimental::OffsetView<T,P...> & src
1856 ,
typename std::enable_if<!Impl::MirrorOffsetViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1857 return typename Kokkos::Experimental::Impl::MirrorOffsetViewType<Space,T,P ...>::view_type(src.label(),src.layout(),
1858 { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1859 src.begin(5), src.begin(6), src.begin(7) } );
KOKKOS_INLINE_FUNCTION bool operator==(const complex< RealType1 > &x, const complex< RealType2 > &y)
Equality operator for two complex numbers.
KOKKOS_INLINE_FUNCTION bool operator!=(const complex< RealType1 > &x, const complex< RealType2 > &y)
Inequality operator for two complex numbers.
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Derived from the C++17 'std::array'. Dropping the iterator interface.
Replacement for std::pair that works on CUDA devices.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
void deep_copy(const View< 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)
Deep copy a value from Host memory into a view.
first_type first
The first element of the pair.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices...
KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const View< D, P...> &V)
Temporary free function rank() until rank() is implemented in the View.
second_type second
The second element of the pair.