Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_OffsetView.hpp
1 /*
2  * Kokkos_OffsetView.hpp
3  *
4  * Created on: Apr 23, 2018
5  * Author: swbova
6  */
7 
8 #ifndef KOKKOS_OFFSETVIEW_HPP_
9 #define KOKKOS_OFFSETVIEW_HPP_
10 
11 
12 #include <Kokkos_Core.hpp>
13 
14 #include <Kokkos_View.hpp>
15 
16 namespace Kokkos {
17 
18  namespace Experimental {
19  //----------------------------------------------------------------------------
20  //----------------------------------------------------------------------------
21 
22  template< class DataType , class ... Properties >
23  class OffsetView ;
24 
25  template< class > struct is_offset_view : public std::false_type {};
26 
27  template< class D, class ... P >
28  struct is_offset_view< OffsetView<D,P...> > : public std::true_type {};
29 
30  template< class D, class ... P >
31  struct is_offset_view< const OffsetView<D,P...> > : public std::true_type {};
32 
33 #define KOKKOS_INVALID_OFFSET int64_t(0)
34 #define KOKKOS_INVALID_INDEX_RANGE {KOKKOS_INVALID_OFFSET, KOKKOS_INVALID_OFFSET}
35 
36  template <typename iType, typename std::enable_if< std::is_integral<iType>::value &&
37  std::is_signed<iType>::value, iType >::type = 0>
38  using IndexRange = Kokkos::Array<iType, 2>;
39 
40 
41  using index_list_type = std::initializer_list<int64_t>;
42 
43 
44  // template <typename iType,
45  // typename std::enable_if< std::is_integral<iType>::value &&
46  // std::is_signed<iType>::value, iType >::type = 0> using min_index_type = std::initializer_list<iType>;
47 
48  namespace Impl {
49 
50  template<class ViewType>
51  struct GetOffsetViewTypeFromViewType {
52 
53  typedef OffsetView<typename ViewType::data_type,typename ViewType::array_layout,
54  typename ViewType::device_type,typename ViewType::memory_traits> type;
55 
56  };
57 
58  template< unsigned , class MapType, class BeginsType >
59  KOKKOS_INLINE_FUNCTION
60  bool offsetview_verify_operator_bounds( const MapType &, const BeginsType & )
61  { return true ; }
62 
63  template< unsigned R , class MapType , class BeginsType, class iType , class ... Args >
64  KOKKOS_INLINE_FUNCTION
65  bool offsetview_verify_operator_bounds
66  ( const MapType & map
67  , const BeginsType & begins
68  , const iType & i
69  , Args ... args
70  )
71  {
72 
73  const bool legalIndex = ( int64_t(i) >= begins[R] ) &&
74  ( int64_t(i) <= int64_t(begins[R] + map.extent(R) - 1) );
75  return legalIndex
76  && offsetview_verify_operator_bounds<R+1>( map , begins, args ... );
77  }
78  template< unsigned , class MapType, class BeginsType >
79  inline
80  void offsetview_error_operator_bounds( char * , int , const MapType & , const BeginsType &)
81  {}
82 
83  template< unsigned R , class MapType , class BeginsType , class iType , class ... Args >
84  inline
85  void offsetview_error_operator_bounds
86  ( char * buf
87  , int len
88  , const MapType & map
89  , const BeginsType begins
90  , const iType & i
91  , Args ... args
92  )
93  {
94  const int64_t b = begins[R];
95  const int64_t e = b + map.extent(R) - 1;
96  const int n =
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) ? ',' : ')' )
102  );
103  offsetview_error_operator_bounds<R+1>(buf+n,len-n,map,begins,args...);
104  }
105 
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 )
111  {
112  if ( ! offsetview_verify_operator_bounds<0>( map , begins, args ... ) ) {
113 #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
114  enum { LEN = 1024 };
115  char buffer[ LEN ];
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));
120 #else
121  /* Check #1: is there a SharedAllocationRecord?
122  (we won't use it, but if its not there then there isn't
123  a corresponding SharedAllocationHeader containing a label).
124  This check should cover the case of Views that don't
125  have the Unmanaged trait but were initialized by pointer. */
126  if (tracker.has_record()) {
127  Kokkos::Impl::operator_bounds_error_on_device<MapType>(
128  map, Kokkos::Impl::has_printable_label_typedef<MapType>());
129  } else {
130  Kokkos::abort("OffsetView bounds error");
131  }
132 #endif
133  }
134  }
135 
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)
140  {
141  bool isBad = false;
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";
146  isBad = true;
147  }
148 
149  size_t numOffsets = 0;
150  for(size_t i = 0; i < minIndices.size(); ++i ){
151  if( minIndices.begin()[i] != -KOKKOS_INVALID_OFFSET) numOffsets++;
152  }
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) + " ).";
156  isBad = true;
157  }
158 
159  if(isBad) Kokkos::abort(message.c_str());
160  }
161 #endif
162 
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)
166  {
167  if (rank_dynamic != rank) {
168  Kokkos::abort("The full rank of an OffsetView must be the same as the dynamic rank.");
169  }
170  size_t numOffsets = 0;
171  for(size_t i = 0; i < minIndices.size(); ++i ){
172  if( minIndices.begin()[i] != -KOKKOS_INVALID_OFFSET) numOffsets++;
173  }
174  if (numOffsets != rank) {
175  Kokkos::abort("The number of offsets provided to an OffsetView constructor must equal the dynamic rank.");
176  }
177 
178  }
179  }
180 
181  template< class DataType , class ... Properties >
182  class OffsetView : public ViewTraits< DataType , Properties ... > {
183  public:
184 
185  typedef ViewTraits< DataType , Properties ... > traits ;
186 
187 
188 
189  private:
190 
191  template< class , class ... > friend class OffsetView ;
192  template< class , class ... > friend class View ; //FIXME delete this line
193  template< class , class ... > friend class Kokkos::Impl::ViewMapping ;
194 
195 
196  typedef Kokkos::Impl::ViewMapping< traits , void > map_type ;
197  typedef Kokkos::Impl::SharedAllocationTracker track_type ;
198  public:
199  enum { Rank = map_type::Rank };
200  typedef Kokkos::Array<int64_t, Rank> begins_type ;
201 
202 
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;
207  }
208 
209  KOKKOS_INLINE_FUNCTION
210  begins_type begins() const { return m_begins;}
211 
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);}
215 
216 
217  private:
218  track_type m_track ;
219  map_type m_map ;
220  begins_type m_begins;
221 
222  public:
223  //----------------------------------------
225  typedef OffsetView< typename traits::scalar_array_type ,
226  typename traits::array_layout ,
227  typename traits::device_type ,
228  typename traits::memory_traits >
229  array_type ;
230 
232  typedef OffsetView< typename traits::const_data_type ,
233  typename traits::array_layout ,
234  typename traits::device_type ,
235  typename traits::memory_traits >
236  const_type ;
237 
239  typedef OffsetView< typename traits::non_const_data_type ,
240  typename traits::array_layout ,
241  typename traits::device_type ,
242  typename traits::memory_traits >
243  non_const_type ;
244 
246  typedef OffsetView< typename traits::non_const_data_type ,
247  typename traits::array_layout ,
248  typename traits::host_mirror_space >
249  HostMirror ;
250 
251  //----------------------------------------
252  // Domain rank and extents
253 
256  //KOKKOS_INLINE_FUNCTION
257  //static
258  //constexpr unsigned rank() { return map_type::Rank; }
259 
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); }
265 
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)); }
271 
272  KOKKOS_INLINE_FUNCTION constexpr
273  typename traits::array_layout layout() const
274  { return m_map.layout(); }
275 
276 
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(); }
285 
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(); }
294 
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())))))));
307  }
308 
309  template< typename iType >
310  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const { m_map.stride(s); }
311 
312  //----------------------------------------
313  // Range span is the span which contains all members.
314 
315  typedef typename map_type::reference_type reference_type ;
316  typedef typename map_type::pointer_type pointer_type ;
317 
318  enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
319 
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(); }
323 
324  //----------------------------------------
325  // Allow specializations to query their specialized map
326 
327  KOKKOS_INLINE_FUNCTION
328  const Kokkos::Impl::ViewMapping< traits , void > &
329  implementation_map() const { return m_map ; }
330 
331  //----------------------------------------
332 
333  private:
334 
335  enum {
336  is_layout_left = std::is_same< typename traits::array_layout
337  , Kokkos::LayoutLeft >::value ,
338 
339  is_layout_right = std::is_same< typename traits::array_layout
340  , Kokkos::LayoutRight >::value ,
341 
342  is_layout_stride = std::is_same< typename traits::array_layout
343  , Kokkos::LayoutStride >::value ,
344 
345  is_default_map =
346  std::is_same< typename traits::specialize , void >::value &&
347  ( is_layout_left || is_layout_right || is_layout_stride )
348  };
349 
350  template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible > struct verify_space
351  { KOKKOS_FORCEINLINE_FUNCTION static void check() {} };
352 
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");
356  };
357  };
358 
359 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
360 
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 ;
364 
365 #else
366 
367 #define KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( ARG ) \
368  OffsetView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
369 
370 #endif
371  public:
372 
373  //------------------------------
374  // Rank 0 operator()
375 
376  KOKKOS_FORCEINLINE_FUNCTION
377  reference_type
378  operator()() const
379  {
380  return m_map.reference();
381  }
382  //------------------------------
383  // Rank 1 operator()
384 
385 
386  template< typename I0>
387  KOKKOS_FORCEINLINE_FUNCTION
388  typename std::enable_if<
389  ( Kokkos::Impl::are_integral<I0>::value
390  && ( 1 == Rank )
391  && ! is_default_map
392  ), reference_type >::type
393  operator()( const I0 & i0) const
394  {
395 
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);
399  }
400 
401  template< typename I0>
402  KOKKOS_FORCEINLINE_FUNCTION
403  typename std::enable_if<
404  ( Kokkos::Impl::are_integral<I0>::value
405  && ( 1 == Rank )
406  && is_default_map
407  && ! is_layout_stride
408  ), reference_type >::type
409  operator()( const I0 & i0 ) const
410  {
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 ];
414  }
415 
416  template< typename I0 >
417  KOKKOS_FORCEINLINE_FUNCTION
418  typename std::enable_if<
419  ( Kokkos::Impl::are_integral<I0>::value
420  && ( 1 == Rank )
421  && is_default_map
422  && is_layout_stride
423  ), reference_type >::type
424  operator()( const I0 & i0) const
425  {
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 ];
429  }
430  //------------------------------
431  // Rank 1 operator[]
432 
433  template< typename I0 >
434  KOKKOS_FORCEINLINE_FUNCTION
435  typename std::enable_if<
436  ( Kokkos::Impl::are_integral<I0>::value
437  && ( 1 == Rank )
438  && ! is_default_map
439  ), reference_type >::type
440  operator[]( const I0 & i0 ) const
441  {
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);
445  }
446 
447  template< typename I0 >
448  KOKKOS_FORCEINLINE_FUNCTION
449  typename std::enable_if<
450  ( Kokkos::Impl::are_integral<I0>::value
451  && ( 1 == Rank )
452  && is_default_map
453  && ! is_layout_stride
454  ), reference_type >::type
455  operator[]( const I0 & i0 ) const
456  {
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 ];
460  }
461 
462  template< typename I0 >
463  KOKKOS_FORCEINLINE_FUNCTION
464  typename std::enable_if<
465  ( Kokkos::Impl::are_integral<I0>::value
466  && ( 1 == Rank )
467  && is_default_map
468  && is_layout_stride
469  ), reference_type >::type
470  operator[]( const I0 & i0 ) const
471  {
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 ];
475  }
476 
477 
478  //------------------------------
479  // Rank 2
480 
481  template< typename I0 , typename I1 >
482  KOKKOS_FORCEINLINE_FUNCTION
483  typename std::enable_if<
484  ( Kokkos::Impl::are_integral<I0,I1>::value
485  && ( 2 == Rank )
486  && ! is_default_map
487  ), reference_type >::type
488  operator()( const I0 & i0 , const I1 & i1) const
489  {
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);
494  }
495 
496  template< typename I0 , typename I1 >
497  KOKKOS_FORCEINLINE_FUNCTION
498  typename std::enable_if<
499  ( Kokkos::Impl::are_integral<I0,I1>::value
500  && ( 2 == Rank )
501  && is_default_map
502  && is_layout_left && ( traits::rank_dynamic == 0 )
503  ), reference_type >::type
504  operator()( const I0 & i0 , const I1 & i1) const
505  {
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 ];
510  }
511 
512  template< typename I0 , typename I1>
513  KOKKOS_FORCEINLINE_FUNCTION
514  typename std::enable_if<
515  ( Kokkos::Impl::are_integral<I0,I1>::value
516  && ( 2 == Rank )
517  && is_default_map
518  && is_layout_left && ( traits::rank_dynamic != 0 )
519  ), reference_type >::type
520  operator()( const I0 & i0 , const I1 & i1) const
521  {
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 ];
526  }
527 
528  template< typename I0 , typename I1 >
529  KOKKOS_FORCEINLINE_FUNCTION
530  typename std::enable_if<
531  ( Kokkos::Impl::are_integral<I0,I1>::value
532  && ( 2 == Rank )
533  && is_default_map
534  && is_layout_right && ( traits::rank_dynamic == 0 )
535  ), reference_type >::type
536  operator()( const I0 & i0 , const I1 & i1 ) const
537  {
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 ];
542  }
543 
544  template< typename I0 , typename I1 >
545  KOKKOS_FORCEINLINE_FUNCTION
546  typename std::enable_if<
547  ( Kokkos::Impl::are_integral<I0,I1>::value
548  && ( 2 == Rank )
549  && is_default_map
550  && is_layout_right && ( traits::rank_dynamic != 0 )
551  ), reference_type >::type
552  operator()( const I0 & i0 , const I1 & i1 ) const
553  {
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 ];
558  }
559 
560  template< typename I0 , typename I1>
561  KOKKOS_FORCEINLINE_FUNCTION
562  typename std::enable_if<
563  ( Kokkos::Impl::are_integral<I0,I1>::value
564  && ( 2 == Rank )
565  && is_default_map
566  && is_layout_stride
567  ), reference_type >::type
568  operator()( const I0 & i0 , const I1 & i1 ) const
569  {
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 ];
575  }
576 
577  //------------------------------
578  // Rank 3
579 
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
584  && ( 3 == Rank )
585  && is_default_map
586  ), reference_type >::type
587  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2) const
588  {
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) ];
594  }
595 
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
600  && ( 3 == Rank )
601  && ! is_default_map
602  ), reference_type >::type
603  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2) const
604  {
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);
610  }
611 
612  //------------------------------
613  // Rank 4
614 
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
619  && ( 4 == Rank )
620  && is_default_map
621  ), reference_type >::type
622  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3) const
623  {
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) ];
630  }
631 
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
636  && ( 4 == Rank )
637  && ! is_default_map
638  ), reference_type >::type
639  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3) const
640  {
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);
647  }
648 
649  //------------------------------
650  // Rank 5
651 
652  template< typename I0 , typename I1 , typename I2 , typename I3
653  , typename I4>
654  KOKKOS_FORCEINLINE_FUNCTION
655  typename std::enable_if<
656  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4>::value
657  && ( 5 == Rank )
658  && is_default_map
659  ), reference_type >::type
660  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
661  , const I4 & i4 ) const
662  {
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) ];
670  }
671 
672  template< typename I0 , typename I1 , typename I2 , typename I3
673  , typename I4>
674  KOKKOS_FORCEINLINE_FUNCTION
675  typename std::enable_if<
676  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4>::value
677  && ( 5 == Rank )
678  && ! is_default_map
679  ), reference_type >::type
680  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
681  , const I4 & i4) const
682  {
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);
690  }
691 
692  //------------------------------
693  // Rank 6
694 
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
700  && ( 6 == Rank )
701  && is_default_map
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
705  {
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) ];
714  }
715 
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
721  && ( 6 == Rank )
722  && ! is_default_map
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
726  {
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);
735  }
736 
737  //------------------------------
738  // Rank 7
739 
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
745  && ( 7 == Rank )
746  && is_default_map
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
750  {
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) ];
760  }
761 
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
767  && ( 7 == Rank )
768  && ! is_default_map
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
772  {
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);
782  }
783 
784  //------------------------------
785  // Rank 8
786 
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
792  && ( 8 == Rank )
793  && is_default_map
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
797  {
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) ];
808  }
809 
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
815  && ( 8 == Rank )
816  && ! is_default_map
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
820  {
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);
831  }
832 
833 
834 #undef KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY
835 
836  //----------------------------------------
837  // Standard destructor, constructors, and assignment operators
838 
839  KOKKOS_INLINE_FUNCTION
840  ~OffsetView() {}
841 
842  KOKKOS_INLINE_FUNCTION
843  OffsetView() : m_track(), m_map() {
844 
845  for(size_t i = 0; i < Rank; ++i) m_begins[i] = KOKKOS_INVALID_INDEX;
846  }
847 
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) {}
851 
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)) {}
855 
856  KOKKOS_INLINE_FUNCTION
857  OffsetView & operator = ( const OffsetView & rhs ) {
858  m_track = rhs.m_track ;
859  m_map = rhs.m_map ;
860  m_begins = rhs.m_begins;
861  return *this ;
862  }
863 
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) ;
869  return *this ;
870  }
871 
872  //interoperability with View
873  private:
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;
878  public:
879 
880  KOKKOS_INLINE_FUNCTION
881  view_type view() const {
882 
883  view_type v(m_track, m_map);
884  return v ;
885  }
886 
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(){
891 
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 );
896 
897  for (int i = 0; i < aview.Rank; ++i) {
898  m_begins[i] = 0;
899  }
900  }
901 
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(){
907 
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 );
912 
913 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
914  Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
915 #else
916  Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
917 
918 #endif
919 
920  for (size_t i = 0; i < minIndices.size(); ++i) {
921  m_begins[i] = minIndices.begin()[i];
922  }
923  }
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){
929 
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 );
934 
935 
936  //#ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
937  // Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
938  //#else
939  // Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
940  //
941  //#endif
942 
943  }
944 
945  // may assign unmanaged from managed.
946 
947 
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 )
952  , m_map()
953  , m_begins(rhs.m_begins)
954  {
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 ); //swb what about assign?
959  }
960 
961 
962  //----------------------------------------
963  // Allocation tracking properties
964  KOKKOS_INLINE_FUNCTION
965  int use_count() const
966  { return m_track.use_count(); }
967 
968  inline
969  const std::string label() const
970  { return m_track.template get_label< typename traits::memory_space >(); }
971 
972 
973  template< typename Label>
974  explicit inline
975  OffsetView( const Label & arg_label
976  ,typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value , const index_list_type >::type
977  range0
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
985 
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] })
994  {
995 
996  }
997 
998 
999 
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
1005  )
1006  : m_track() // No memory tracking
1007  , m_map( arg_prop , arg_layout )
1008  {
1009 
1010 
1011  for (size_t i = 0; i < minIndices.size(); ++i) {
1012  m_begins[i] = minIndices.begin()[i];
1013  }
1014  static_assert(
1015  std::is_same< pointer_type
1016  , typename Kokkos::Impl::ViewCtorProp< P... >::pointer_type
1017  >::value ,
1018  "When constructing OffsetView to wrap user memory, you must supply matching pointer type" );
1019  }
1020 
1021  template<class ... P >
1022  explicit inline
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
1026  )
1027  : m_track()
1028  , m_map()
1029 
1030  {
1031 
1032  for(size_t i = 0; i < Rank; ++i)
1033  m_begins[i] = minIndices.begin()[i];
1034 
1035  // Append layout and spaces if not input
1036  typedef Kokkos::Impl::ViewCtorProp< P ... > alloc_prop_input ;
1037 
1038  // use 'std::integral_constant<unsigned,I>' for non-types
1039  // to avoid duplicate class error.
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
1047  >::type
1048  , typename std::conditional
1049  < alloc_prop_input::has_execution_space
1050  , std::integral_constant<unsigned,2>
1051  , typename traits::device_type::execution_space
1052  >::type
1053  > alloc_prop ;
1054 
1055  static_assert( traits::is_managed
1056  , "OffsetView allocation constructor requires managed memory" );
1057 
1058  if ( alloc_prop::initialize &&
1059 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
1060  ! alloc_prop::execution_space::is_initialized()
1061 #else
1062  ! alloc_prop::execution_space::impl_is_initialized()
1063 #endif
1064  ) {
1065  // If initializing view data then
1066  // the execution space must be initialized.
1067  Kokkos::Impl::throw_runtime_exception("Constructing OffsetView and initializing data with uninitialized execution space");
1068  }
1069 
1070  // Copy the input allocation properties with possibly defaulted properties
1071  alloc_prop prop( arg_prop );
1072 
1073  //------------------------------------------------------------
1074 #if defined( KOKKOS_ENABLE_CUDA )
1075  // If allocating in CudaUVMSpace must fence before and after
1076  // the allocation to protect against possible concurrent access
1077  // on the CPU and the GPU.
1078  // Fence using the trait's executon space (which will be Kokkos::Cuda)
1079  // to avoid incomplete type errors from usng Kokkos::Cuda directly.
1080  if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
1081  traits::device_type::memory_space::execution_space::fence();
1082  }
1083 #endif
1084  //------------------------------------------------------------
1085 
1086  Kokkos::Impl::SharedAllocationRecord<> *
1087  record = m_map.allocate_shared( prop , arg_layout );
1088 
1089  //------------------------------------------------------------
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();
1093  }
1094 #endif
1095  //------------------------------------------------------------
1096 
1097  // Setup and initialization complete, start tracking
1098  m_track.assign_allocated_record_to_uninitialized( record );
1099 
1100 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
1101  Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
1102 #else
1103  Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
1104 
1105 #endif
1106 
1107  }
1108 
1109 
1110  };
1111 
1112 
1113 
1118  template < typename D , class ... P >
1119  KOKKOS_INLINE_FUNCTION
1120  constexpr unsigned rank( const OffsetView<D , P...> & V ) { return V.Rank; } //Temporary until added to view
1121 
1122  //----------------------------------------------------------------------------
1123  //----------------------------------------------------------------------------
1124  namespace Impl {
1125 
1126  template< class T >
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)
1130  {
1131  return arg - offset;
1132  }
1133 
1134  KOKKOS_INLINE_FUNCTION
1135  Kokkos::Impl::ALL_t
1136  shift_input(const Kokkos::Impl::ALL_t arg, const int64_t offset)
1137  {
1138  return arg;
1139  }
1140 
1141  template< class T >
1142  KOKKOS_INLINE_FUNCTION
1143  typename std::enable_if< std::is_integral<T>::value, Kokkos::pair<T,T> >::type
1144  shift_input(const Kokkos::pair<T, T> arg, const int64_t offset)
1145  {
1146 
1147  return Kokkos::make_pair<T,T>(arg.first - offset, arg.second - offset);
1148 
1149  }
1150  template< class T >
1151  inline
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)
1154  {
1155 
1156  return std::make_pair<T,T>(arg.first - offset, arg.second - offset);
1157 
1158  }
1159 
1160  template <size_t N, class Arg, class A>
1161  KOKKOS_INLINE_FUNCTION
1162  void
1163  map_arg_to_new_begin(const size_t i,
1164  Kokkos::Array<int64_t, N> &subviewBegins, typename std::enable_if< N != 0, const Arg>::type shiftedArg,
1165  const Arg arg, const A viewBegins, size_t & counter) {
1166 
1167  if( !std::is_integral<Arg>::value) {
1168  subviewBegins[counter] = shiftedArg == arg ? viewBegins[i] : 0;
1169  counter++;
1170  }
1171  }
1172 
1173  template <size_t N, class Arg, class A>
1174  KOKKOS_INLINE_FUNCTION
1175  void
1176  map_arg_to_new_begin(const size_t i,
1177  Kokkos::Array<int64_t, N> &subviewBegins, typename std::enable_if< N == 0, const Arg>::type shiftedArg,
1178  const Arg arg, const A viewBegins, size_t & counter) {
1179 
1180  }
1181 
1182 
1183  template< class D, class ... P , class T >
1184  KOKKOS_INLINE_FUNCTION
1185  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1186  < void /* deduce subview type from source view traits */
1187  , ViewTraits< D , P... >
1188  , T
1189  >::type >::type
1190  subview_offset(const OffsetView< D, P... > & src, T arg) {
1191 
1192  auto theView = src.view();
1193  auto begins = src.begins();
1194 
1195  T shiftedArg = shift_input(arg, begins[0]);
1196 
1197  constexpr size_t rank = Kokkos::Impl::ViewMapping
1198  < void /* deduce subview type from source view traits */
1199  , ViewTraits< D , P... >
1200  , T>::type::Rank;
1201 
1202  auto theSubview = Kokkos::subview( theView , shiftedArg);
1203 
1204  Kokkos::Array<int64_t, rank> subviewBegins;
1205  size_t counter = 0;
1206  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg, arg, begins, counter);
1207 
1208  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1209  void /* deduce subview type from source view traits */
1210  , ViewTraits< D , P... > , T >::type >::type offsetView(theSubview, subviewBegins);
1211 
1212  return offsetView;
1213 
1214  }
1215 
1216  template< class D, class ... P , class T0, class T1 >
1217  KOKKOS_INLINE_FUNCTION
1218  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1219  < void /* deduce subview type from source view traits */
1220  , ViewTraits< D , P... >
1221  , T0, T1
1222  >::type >::type
1223  subview_offset(const Kokkos::Experimental::OffsetView< D, P... > & src, T0 arg0, T1 arg1) {
1224 
1225  auto theView = src.view();
1226  auto begins = src.begins();
1227 
1228  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1229  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1230 
1231  auto theSubview = Kokkos::subview(theView , shiftedArg0, shiftedArg1);
1232  constexpr size_t rank = Kokkos::Impl::ViewMapping
1233  < void /* deduce subview type from source view traits */
1234  , ViewTraits< D , P... >
1235  , T0, T1>::type::Rank;
1236 
1237  Kokkos::Array<int64_t, rank> subviewBegins;
1238  size_t counter = 0;
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);
1241 
1242  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1243  void /* deduce subview type from source view traits */
1244  , ViewTraits< D , P... > , T0, T1 >::type >::type offsetView(theSubview, subviewBegins);
1245 
1246  return offsetView;
1247 
1248  }
1249 
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
1253  < void /* deduce subview type from source view traits */
1254  , ViewTraits< D , P... >
1255  , T0, T1, T2
1256  >::type >::type
1257  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2) {
1258 
1259  auto theView = src.view();
1260  auto begins = src.begins();
1261 
1262  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1263  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1264  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1265 
1266  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2);
1267 
1268  constexpr size_t rank = Kokkos::Impl::ViewMapping
1269  < void /* deduce subview type from source view traits */
1270  , ViewTraits< D , P... >
1271  , T0, T1, T2>::type::Rank;
1272 
1273  Kokkos::Array<int64_t, rank> subviewBegins;
1274 
1275  size_t counter = 0;
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);
1279 
1280  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1281  void /* deduce subview type from source view traits */
1282  , ViewTraits< D , P... > , T0, T1, T2 >::type >::type offsetView(theSubview, subviewBegins);
1283 
1284  return offsetView;
1285  }
1286 
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
1290  < void /* deduce subview type from source view traits */
1291  , ViewTraits< D , P... >
1292  , T0, T1, T2, T3
1293  >::type >::type
1294  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
1295 
1296  auto theView = src.view();
1297  auto begins = src.begins();
1298 
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]);
1303 
1304  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3);
1305 
1306  constexpr size_t rank = Kokkos::Impl::ViewMapping
1307  < void /* deduce subview type from source view traits */
1308  , ViewTraits< D , P... >
1309  , T0, T1, T2, T3>::type::Rank;
1310  Kokkos::Array<int64_t, rank> subviewBegins;
1311 
1312  size_t counter = 0;
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);
1317 
1318  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1319  void /* deduce subview type from source view traits */
1320  , ViewTraits< D , P... > , T0, T1, T2, T3 >::type >::type offsetView(theSubview, subviewBegins);
1321 
1322  return offsetView;
1323  }
1324 
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
1328  < void /* deduce subview type from source view traits */
1329  , ViewTraits< D , P... >
1330  , T0, T1, T2, T3, T4
1331  >::type >::type
1332  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
1333 
1334  auto theView = src.view();
1335  auto begins = src.begins();
1336 
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]);
1342 
1343  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4);
1344 
1345  constexpr size_t rank = Kokkos::Impl::ViewMapping
1346  < void /* deduce subview type from source view traits */
1347  , ViewTraits< D , P... >
1348  , T0, T1, T2, T3, T4>::type::Rank;
1349  Kokkos::Array<int64_t, rank> subviewBegins;
1350 
1351  size_t counter = 0;
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);
1357 
1358  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1359  void /* deduce subview type from source view traits */
1360  , ViewTraits< D , P... > , T0, T1, T2, T3, T4 >::type >::type offsetView(theSubview, subviewBegins);
1361 
1362  return offsetView;
1363  }
1364 
1365  template< class D, class ... P , class T0, class T1, class T2, class T3, class T4,
1366  class T5 >
1367  KOKKOS_INLINE_FUNCTION
1368  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1369  < void /* deduce subview type from source view traits */
1370  , ViewTraits< D , P... >
1371  , T0, T1, T2, T3, T4, T5
1372  >::type >::type
1373  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
1374 
1375  auto theView = src.view();
1376  auto begins = src.begins();
1377 
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]);
1384 
1385  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5);
1386 
1387  constexpr size_t rank = Kokkos::Impl::ViewMapping
1388  < void /* deduce subview type from source view traits */
1389  , ViewTraits< D , P... >
1390  , T0, T1, T2, T3, T4, T5>::type::Rank;
1391 
1392  Kokkos::Array<int64_t, rank> subviewBegins;
1393 
1394  size_t counter = 0;
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);
1401 
1402  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1403  void /* deduce subview type from source view traits */
1404  , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5 >::type >::type offsetView(theSubview, subviewBegins);
1405 
1406  return offsetView;
1407  }
1408  template< class D, class ... P , class T0, class T1, class T2, class T3, class T4,
1409  class T5, class T6>
1410  KOKKOS_INLINE_FUNCTION
1411  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1412  < void /* deduce subview type from source view traits */
1413  , ViewTraits< D , P... >
1414  , T0, T1, T2, T3, T4, T5, T6
1415  >::type >::type
1416  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
1417  T6 arg6) {
1418 
1419  auto theView = src.view();
1420  auto begins = src.begins();
1421 
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]);
1429 
1430  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5,
1431  shiftedArg6);
1432 
1433  constexpr size_t rank = Kokkos::Impl::ViewMapping
1434  < void /* deduce subview type from source view traits */
1435  , ViewTraits< D , P... >
1436  , T0, T1, T2, T3, T4, T5, T6>::type::Rank;
1437 
1438  Kokkos::Array<int64_t, rank> subviewBegins;
1439 
1440  size_t counter = 0;
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);
1448 
1449  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1450  void /* deduce subview type from source view traits */
1451  , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5,
1452  T6 >::type >::type offsetView(theSubview, subviewBegins);
1453 
1454  return offsetView;
1455  }
1456 
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
1461  < void /* deduce subview type from source view traits */
1462  , ViewTraits< D , P... >
1463  , T0, T1, T2, T3, T4, T5, T6, T7
1464  >::type >::type
1465  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
1466  T6 arg6, T7 arg7) {
1467 
1468  auto theView = src.view();
1469  auto begins = src.begins();
1470 
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]);
1479 
1480  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5,
1481  shiftedArg6, shiftedArg7);
1482 
1483  constexpr size_t rank = Kokkos::Impl::ViewMapping
1484  < void /* deduce subview type from source view traits */
1485  , ViewTraits< D , P... >
1486  , T0, T1, T2, T3, T4, T5, T6, T7>::type::Rank;
1487 
1488  Kokkos::Array<int64_t, rank> subviewBegins;
1489 
1490  size_t counter = 0;
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);
1499 
1500  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1501  void /* deduce subview type from source view traits */
1502  , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5,
1503  T6, T7 >::type >::type offsetView(theSubview, subviewBegins);
1504 
1505  return offsetView;
1506  }
1507  }
1508 
1509  template< class D, class ... P , class ... Args >
1510  KOKKOS_INLINE_FUNCTION
1511  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1512  < void /* deduce subview type from source view traits */
1513  , ViewTraits< D , P... >
1514  , Args ...
1515  >::type >::type
1516  subview( const OffsetView< D, P... > & src , Args ... args )
1517  {
1518  static_assert( OffsetView< D , P... >::Rank == sizeof...(Args) ,
1519  "subview requires one argument for each source OffsetView rank" );
1520 
1521 
1522  return Kokkos::Experimental::Impl::subview_offset(src, args...);
1523 
1524 
1525  }
1526 
1527  }
1528 }
1529 //----------------------------------------------------------------------------
1530 //----------------------------------------------------------------------------
1531 
1532 namespace Kokkos {
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 )
1538  {
1539  // Same data, layout, dimensions
1540  typedef ViewTraits<LT,LP...> lhs_traits ;
1541  typedef ViewTraits<RT,RP...> rhs_traits ;
1542 
1543  return
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)
1569  ;
1570  }
1571 
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 )
1576  {
1577  return ! ( operator==(lhs,rhs) );
1578  }
1579 
1580  template< class LT , class ... LP , class RT , class ... RP >
1581  KOKKOS_INLINE_FUNCTION
1582  bool operator == ( const View<LT,LP...> & lhs ,
1583  const OffsetView<RT,RP...> & rhs )
1584  {
1585  // Same data, layout, dimensions
1586  typedef ViewTraits<LT,LP...> lhs_traits ;
1587  typedef ViewTraits<RT,RP...> rhs_traits ;
1588 
1589  return
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)
1607  ;
1608  }
1609 
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;}
1615 
1616  }
1617 } /* namespace Kokkos */
1618 
1619 //----------------------------------------------------------------------------
1620 //----------------------------------------------------------------------------
1621 
1622 
1623 namespace Kokkos {
1624  namespace Experimental {
1625  template< class DT , class ... DP >
1626  inline
1627  void deep_copy
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
1632  >::type * = 0 )
1633  {
1634  static_assert(
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" );
1638 
1639  auto dstView = dst.view();
1640  Kokkos::deep_copy( dstView , value );
1641 
1642  }
1643 
1644  template< class DT , class ... DP , class ST , class ... SP >
1645  inline
1646  void deep_copy
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
1651  >::type * = 0 )
1652  {
1653  static_assert(
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" );
1657 
1658  auto dstView = dst.view();
1659  Kokkos::deep_copy( dstView , value.view() );
1660 
1661  }
1662  template< class DT , class ... DP , class ST , class ... SP >
1663  inline
1664  void deep_copy
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
1669  >::type * = 0 )
1670  {
1671  static_assert(
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" );
1675 
1676  auto dstView = dst.view();
1677  Kokkos::deep_copy( dstView , value);
1678 
1679  }
1680 
1681  template< class DT , class ... DP , class ST , class ... SP >
1682  inline
1683  void deep_copy
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
1688  >::type * = 0 )
1689  {
1690  static_assert(
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" );
1694 
1695  Kokkos::deep_copy( dst , value.view() );
1696 
1697  }
1698  namespace Impl {
1699 
1700  // Deduce Mirror Types
1701  template<class Space, class T, class ... P>
1702  struct MirrorOffsetViewType {
1703  // The incoming view_type
1704  typedef typename Kokkos::Experimental::OffsetView<T,P...> src_view_type;
1705  // The memory space for the mirror view
1706  typedef typename Space::memory_space memory_space;
1707  // Check whether it is the same memory space
1708  enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
1709  // The array_layout
1710  typedef typename src_view_type::array_layout array_layout;
1711  // The data type (we probably want it non-const since otherwise we can't even deep_copy to it.
1712  typedef typename src_view_type::non_const_data_type data_type;
1713  // The destination view type if it is not the same memory space
1714  typedef Kokkos::Experimental::OffsetView<data_type,array_layout,Space> dest_view_type;
1715  // If it is the same memory_space return the existsing view_type
1716  // This will also keep the unmanaged trait if necessary
1717  typedef typename std::conditional<is_same_memspace,src_view_type,dest_view_type>::type view_type;
1718  };
1719 
1720  template<class Space, class T, class ... P>
1721  struct MirrorOffsetType {
1722  // The incoming view_type
1723  typedef typename Kokkos::Experimental::OffsetView<T,P...> src_view_type;
1724  // The memory space for the mirror view
1725  typedef typename Space::memory_space memory_space;
1726  // Check whether it is the same memory space
1727  enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
1728  // The array_layout
1729  typedef typename src_view_type::array_layout array_layout;
1730  // The data type (we probably want it non-const since otherwise we can't even deep_copy to it.
1731  typedef typename src_view_type::non_const_data_type data_type;
1732  // The destination view type if it is not the same memory space
1733  typedef Kokkos::Experimental::OffsetView<data_type,array_layout,Space> view_type;
1734  };
1735 
1736  }
1737 
1738  template< class T , class ... P >
1739  inline
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
1744  , Kokkos::LayoutStride >::value
1745  >::type * = 0
1746  )
1747  {
1748  typedef OffsetView<T,P...> src_type ;
1749  typedef typename src_type::HostMirror dst_type ;
1750 
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) });
1757  }
1758 
1759  template< class T , class ... P >
1760  inline
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
1765  , Kokkos::LayoutStride >::value
1766  >::type * = 0
1767  )
1768  {
1769  typedef OffsetView<T,P...> src_type ;
1770  typedef typename src_type::HostMirror dst_type ;
1771 
1772  Kokkos::LayoutStride layout ;
1773 
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);
1782 
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();
1791 
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) } );
1795  }
1796 
1797 
1798  // Create a mirror in a new space (specialization for different space)
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) } );
1805  }
1806 
1807 
1808  template< class T , class ... P >
1809  inline
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
1815  >::value
1816  &&
1817  std::is_same< typename Kokkos::Experimental::OffsetView<T,P...>::data_type
1818  , typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::data_type
1819  >::value
1820  )>::type * = 0
1821  )
1822  {
1823  return src ;
1824  }
1825 
1826  template< class T , class ... P >
1827  inline
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
1833  >::value
1834  &&
1835  std::is_same< typename Kokkos::Experimental::OffsetView<T,P...>::data_type
1836  , typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::data_type
1837  >::value
1838  )>::type * = 0
1839  )
1840  {
1841  return Kokkos::Experimental::create_mirror( src );
1842  }
1843 
1844  // Create a mirror view in a new space (specialization for same space)
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 ) {
1849  return src;
1850  }
1851 
1852  // Create a mirror view in a new space (specialization for different space)
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) } );
1860  }
1861  //
1862  // // Create a mirror view and deep_copy in a new space (specialization for same space)
1863  // template<class Space, class T, class ... P>
1864  // typename Kokkos::Experimental::Impl::MirrorViewType<Space,T,P ...>::view_type
1865  // create_mirror_view_and_copy(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src
1866  // , std::string const& name = ""
1867  // , typename std::enable_if<Impl::MirrorViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1868  // (void)name;
1869  // return src;
1870  // }
1871  //
1872  // // Create a mirror view and deep_copy in a new space (specialization for different space)
1873  // template<class Space, class T, class ... P>
1874  // typename Kokkos::Experimental::Impl::MirrorViewType<Space,T,P ...>::view_type
1875  // create_mirror_view_and_copy(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src
1876  // , std::string const& name = ""
1877  // , typename std::enable_if<!Impl::MirrorViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1878  // using Mirror = typename Kokkos::Experimental::Impl::MirrorViewType<Space,T,P ...>::view_type;
1879  // std::string label = name.empty() ? src.label() : name;
1880  // auto mirror = Mirror(ViewAllocateWithoutInitializing(label), src.layout(),
1881  // { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1882  // src.begin(5), src.begin(6), src.begin(7) });
1883  // deep_copy(mirror, src);
1884  // return mirror;
1885  // }
1886 
1887  }
1888 } /* namespace Kokkos */
1889 
1890 
1891 //----------------------------------------------------------------------------
1892 //----------------------------------------------------------------------------
1893 
1894 
1895 #endif /* KOKKOS_OFFSETVIEW_HPP_ */
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 &#39;std::array&#39;. Dropping the iterator interface.
Replacement for std::pair that works on CUDA devices.
Definition: Kokkos_Pair.hpp:64
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.
Definition: Kokkos_Pair.hpp:72
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.
Definition: Kokkos_Pair.hpp:74