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 local_dimension) const {
206  return local_dimension < Rank ? m_begins[local_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 local_dimension) const {
215  return begin(local_dimension) + m_map.extent(local_dimension);
216  }
217 
218 
219  private:
220  track_type m_track ;
221  map_type m_map ;
222  begins_type m_begins;
223 
224  public:
225  //----------------------------------------
227  typedef OffsetView< typename traits::scalar_array_type ,
228  typename traits::array_layout ,
229  typename traits::device_type ,
230  typename traits::memory_traits >
231  array_type ;
232 
234  typedef OffsetView< typename traits::const_data_type ,
235  typename traits::array_layout ,
236  typename traits::device_type ,
237  typename traits::memory_traits >
238  const_type ;
239 
241  typedef OffsetView< typename traits::non_const_data_type ,
242  typename traits::array_layout ,
243  typename traits::device_type ,
244  typename traits::memory_traits >
245  non_const_type ;
246 
248  typedef OffsetView< typename traits::non_const_data_type ,
249  typename traits::array_layout ,
250  typename traits::host_mirror_space >
251  HostMirror ;
252 
253  //----------------------------------------
254  // Domain rank and extents
255 
258  //KOKKOS_INLINE_FUNCTION
259  //static
260  //constexpr unsigned rank() { return map_type::Rank; }
261 
262  template< typename iType >
263  KOKKOS_INLINE_FUNCTION constexpr
264  typename std::enable_if< std::is_integral<iType>::value , size_t >::type
265  extent( const iType & r ) const
266  { return m_map.extent(r); }
267 
268  template< typename iType >
269  KOKKOS_INLINE_FUNCTION constexpr
270  typename std::enable_if< std::is_integral<iType>::value , int >::type
271  extent_int( const iType & r ) const
272  { return static_cast<int>(m_map.extent(r)); }
273 
274  KOKKOS_INLINE_FUNCTION constexpr
275  typename traits::array_layout layout() const
276  { return m_map.layout(); }
277 
278 
279  KOKKOS_INLINE_FUNCTION constexpr size_t size() const { return m_map.dimension_0() *
280  m_map.dimension_1() *
281  m_map.dimension_2() *
282  m_map.dimension_3() *
283  m_map.dimension_4() *
284  m_map.dimension_5() *
285  m_map.dimension_6() *
286  m_map.dimension_7(); }
287 
288  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const { return m_map.stride_0(); }
289  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const { return m_map.stride_1(); }
290  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const { return m_map.stride_2(); }
291  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const { return m_map.stride_3(); }
292  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const { return m_map.stride_4(); }
293  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const { return m_map.stride_5(); }
294  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const { return m_map.stride_6(); }
295  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const { return m_map.stride_7(); }
296 
297  template< typename iType >
298  KOKKOS_INLINE_FUNCTION constexpr
299  typename std::enable_if< std::is_integral<iType>::value , size_t >::type
300  stride(iType r) const {
301  return (r == 0 ? m_map.stride_0() :
302  (r == 1 ? m_map.stride_1() :
303  (r == 2 ? m_map.stride_2() :
304  (r == 3 ? m_map.stride_3() :
305  (r == 4 ? m_map.stride_4() :
306  (r == 5 ? m_map.stride_5() :
307  (r == 6 ? m_map.stride_6() :
308  m_map.stride_7())))))));
309  }
310 
311  template< typename iType >
312  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const { m_map.stride(s); }
313 
314  //----------------------------------------
315  // Range span is the span which contains all members.
316 
317  typedef typename map_type::reference_type reference_type ;
318  typedef typename map_type::pointer_type pointer_type ;
319 
320  enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
321 
322  KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return m_map.span(); }
323  KOKKOS_INLINE_FUNCTION bool span_is_contiguous() const { return m_map.span_is_contiguous(); }
324  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const { return m_map.data(); }
325 
326  //----------------------------------------
327  // Allow specializations to query their specialized map
328 
329  KOKKOS_INLINE_FUNCTION
330  const Kokkos::Impl::ViewMapping< traits , void > &
331  implementation_map() const { return m_map ; }
332 
333  //----------------------------------------
334 
335  private:
336 
337  enum {
338  is_layout_left = std::is_same< typename traits::array_layout
339  , Kokkos::LayoutLeft >::value ,
340 
341  is_layout_right = std::is_same< typename traits::array_layout
342  , Kokkos::LayoutRight >::value ,
343 
344  is_layout_stride = std::is_same< typename traits::array_layout
345  , Kokkos::LayoutStride >::value ,
346 
347  is_default_map =
348  std::is_same< typename traits::specialize , void >::value &&
349  ( is_layout_left || is_layout_right || is_layout_stride )
350  };
351 
352  template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible > struct verify_space
353  { KOKKOS_FORCEINLINE_FUNCTION static void check() {} };
354 
355  template< class Space > struct verify_space<Space,false>
356  { KOKKOS_FORCEINLINE_FUNCTION static void check()
357  { Kokkos::abort("Kokkos::View ERROR: attempt to access inaccessible memory space");
358  };
359  };
360 
361 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
362 
363 #define KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( ARG ) \
364  OffsetView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check(); \
365  Kokkos::Experimental::Impl::offsetview_verify_operator_bounds< typename traits::memory_space > ARG ;
366 
367 #else
368 
369 #define KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( ARG ) \
370  OffsetView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
371 
372 #endif
373  public:
374 
375  //------------------------------
376  // Rank 0 operator()
377 
378  KOKKOS_FORCEINLINE_FUNCTION
379  reference_type
380  operator()() const
381  {
382  return m_map.reference();
383  }
384  //------------------------------
385  // Rank 1 operator()
386 
387 
388  template< typename I0>
389  KOKKOS_FORCEINLINE_FUNCTION
390  typename std::enable_if<
391  ( Kokkos::Impl::are_integral<I0>::value
392  && ( 1 == Rank )
393  && ! is_default_map
394  ), reference_type >::type
395  operator()( const I0 & i0) const
396  {
397 
398  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
399  const size_t j0 = i0 - m_begins[0];
400  return m_map.reference(j0);
401  }
402 
403  template< typename I0>
404  KOKKOS_FORCEINLINE_FUNCTION
405  typename std::enable_if<
406  ( Kokkos::Impl::are_integral<I0>::value
407  && ( 1 == Rank )
408  && is_default_map
409  && ! is_layout_stride
410  ), reference_type >::type
411  operator()( const I0 & i0 ) const
412  {
413  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
414  const size_t j0 = i0 - m_begins[0];
415  return m_map.m_impl_handle[ j0 ];
416  }
417 
418  template< typename I0 >
419  KOKKOS_FORCEINLINE_FUNCTION
420  typename std::enable_if<
421  ( Kokkos::Impl::are_integral<I0>::value
422  && ( 1 == Rank )
423  && is_default_map
424  && is_layout_stride
425  ), reference_type >::type
426  operator()( const I0 & i0) const
427  {
428  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
429  const size_t j0 = i0 - m_begins[0];
430  return m_map.m_impl_handle[ m_map.m_impl_offset.m_stride.S0 * j0 ];
431  }
432  //------------------------------
433  // Rank 1 operator[]
434 
435  template< typename I0 >
436  KOKKOS_FORCEINLINE_FUNCTION
437  typename std::enable_if<
438  ( Kokkos::Impl::are_integral<I0>::value
439  && ( 1 == Rank )
440  && ! is_default_map
441  ), reference_type >::type
442  operator[]( const I0 & i0 ) const
443  {
444  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
445  const size_t j0 = i0 - m_begins[0];
446  return m_map.reference(j0);
447  }
448 
449  template< typename I0 >
450  KOKKOS_FORCEINLINE_FUNCTION
451  typename std::enable_if<
452  ( Kokkos::Impl::are_integral<I0>::value
453  && ( 1 == Rank )
454  && is_default_map
455  && ! is_layout_stride
456  ), reference_type >::type
457  operator[]( const I0 & i0 ) const
458  {
459  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
460  const size_t j0 = i0 - m_begins[0];
461  return m_map.m_impl_handle[ j0 ];
462  }
463 
464  template< typename I0 >
465  KOKKOS_FORCEINLINE_FUNCTION
466  typename std::enable_if<
467  ( Kokkos::Impl::are_integral<I0>::value
468  && ( 1 == Rank )
469  && is_default_map
470  && is_layout_stride
471  ), reference_type >::type
472  operator[]( const I0 & i0 ) const
473  {
474  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0) )
475  const size_t j0 = i0 - m_begins[0];
476  return m_map.m_impl_handle[ m_map.m_impl_offset.m_stride.S0 * j0 ];
477  }
478 
479 
480  //------------------------------
481  // Rank 2
482 
483  template< typename I0 , typename I1 >
484  KOKKOS_FORCEINLINE_FUNCTION
485  typename std::enable_if<
486  ( Kokkos::Impl::are_integral<I0,I1>::value
487  && ( 2 == Rank )
488  && ! is_default_map
489  ), reference_type >::type
490  operator()( const I0 & i0 , const I1 & i1) const
491  {
492  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
493  const size_t j0 = i0 - m_begins[0];
494  const size_t j1 = i1 - m_begins[1];
495  return m_map.reference(j0,j1);
496  }
497 
498  template< typename I0 , typename I1 >
499  KOKKOS_FORCEINLINE_FUNCTION
500  typename std::enable_if<
501  ( Kokkos::Impl::are_integral<I0,I1>::value
502  && ( 2 == Rank )
503  && is_default_map
504  && is_layout_left && ( traits::rank_dynamic == 0 )
505  ), reference_type >::type
506  operator()( const I0 & i0 , const I1 & i1) const
507  {
508  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
509  const size_t j0 = i0 - m_begins[0];
510  const size_t j1 = i1 - m_begins[1];
511  return m_map.m_impl_handle[ j0 + m_map.m_impl_offset.m_dim.N0 * j1 ];
512  }
513 
514  template< typename I0 , typename I1>
515  KOKKOS_FORCEINLINE_FUNCTION
516  typename std::enable_if<
517  ( Kokkos::Impl::are_integral<I0,I1>::value
518  && ( 2 == Rank )
519  && is_default_map
520  && is_layout_left && ( traits::rank_dynamic != 0 )
521  ), reference_type >::type
522  operator()( const I0 & i0 , const I1 & i1) const
523  {
524  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
525  const size_t j0 = i0 - m_begins[0];
526  const size_t j1 = i1 - m_begins[1];
527  return m_map.m_impl_handle[ j0 + m_map.m_impl_offset.m_stride * j1 ];
528  }
529 
530  template< typename I0 , typename I1 >
531  KOKKOS_FORCEINLINE_FUNCTION
532  typename std::enable_if<
533  ( Kokkos::Impl::are_integral<I0,I1>::value
534  && ( 2 == Rank )
535  && is_default_map
536  && is_layout_right && ( traits::rank_dynamic == 0 )
537  ), reference_type >::type
538  operator()( const I0 & i0 , const I1 & i1 ) const
539  {
540  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
541  const size_t j0 = i0 - m_begins[0];
542  const size_t j1 = i1 - m_begins[1];
543  return m_map.m_impl_handle[ j1 + m_map.m_impl_offset.m_dim.N1 * j0 ];
544  }
545 
546  template< typename I0 , typename I1 >
547  KOKKOS_FORCEINLINE_FUNCTION
548  typename std::enable_if<
549  ( Kokkos::Impl::are_integral<I0,I1>::value
550  && ( 2 == Rank )
551  && is_default_map
552  && is_layout_right && ( traits::rank_dynamic != 0 )
553  ), reference_type >::type
554  operator()( const I0 & i0 , const I1 & i1 ) const
555  {
556  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
557  const size_t j0 = i0 - m_begins[0];
558  const size_t j1 = i1 - m_begins[1];
559  return m_map.m_impl_handle[ j1 + m_map.m_impl_offset.m_stride * j0 ];
560  }
561 
562  template< typename I0 , typename I1>
563  KOKKOS_FORCEINLINE_FUNCTION
564  typename std::enable_if<
565  ( Kokkos::Impl::are_integral<I0,I1>::value
566  && ( 2 == Rank )
567  && is_default_map
568  && is_layout_stride
569  ), reference_type >::type
570  operator()( const I0 & i0 , const I1 & i1 ) const
571  {
572  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1) )
573  const size_t j0 = i0 - m_begins[0];
574  const size_t j1 = i1 - m_begins[1];
575  return m_map.m_impl_handle[ j0 * m_map.m_impl_offset.m_stride.S0 +
576  j1 * m_map.m_impl_offset.m_stride.S1 ];
577  }
578 
579  //------------------------------
580  // Rank 3
581 
582  template< typename I0 , typename I1 , typename I2 >
583  KOKKOS_FORCEINLINE_FUNCTION
584  typename std::enable_if<
585  ( Kokkos::Impl::are_integral<I0,I1,I2>::value
586  && ( 3 == Rank )
587  && is_default_map
588  ), reference_type >::type
589  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2) const
590  {
591  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2) )
592  const size_t j0 = i0 - m_begins[0];
593  const size_t j1 = i1 - m_begins[1];
594  const size_t j2 = i2 - m_begins[2];
595  return m_map.m_impl_handle[ m_map.m_impl_offset(j0, j1, j2) ];
596  }
597 
598  template< typename I0 , typename I1 , typename I2>
599  KOKKOS_FORCEINLINE_FUNCTION
600  typename std::enable_if<
601  ( Kokkos::Impl::are_integral<I0,I1,I2>::value
602  && ( 3 == Rank )
603  && ! is_default_map
604  ), reference_type >::type
605  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2) const
606  {
607  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2) )
608  const size_t j0 = i0 - m_begins[0];
609  const size_t j1 = i1 - m_begins[1];
610  const size_t j2 = i2 - m_begins[2];
611  return m_map.reference(j0, j1, j2);
612  }
613 
614  //------------------------------
615  // Rank 4
616 
617  template< typename I0 , typename I1 , typename I2 , typename I3>
618  KOKKOS_FORCEINLINE_FUNCTION
619  typename std::enable_if<
620  ( Kokkos::Impl::are_integral<I0,I1,I2,I3>::value
621  && ( 4 == Rank )
622  && is_default_map
623  ), reference_type >::type
624  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3) const
625  {
626  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3) )
627  const size_t j0 = i0 - m_begins[0];
628  const size_t j1 = i1 - m_begins[1];
629  const size_t j2 = i2 - m_begins[2];
630  const size_t j3 = i3 - m_begins[3];
631  return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3) ];
632  }
633 
634  template< typename I0 , typename I1 , typename I2 , typename I3 >
635  KOKKOS_FORCEINLINE_FUNCTION
636  typename std::enable_if<
637  ( Kokkos::Impl::are_integral<I0,I1,I2,I3>::value
638  && ( 4 == Rank )
639  && ! is_default_map
640  ), reference_type >::type
641  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3) const
642  {
643  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3) )
644  const size_t j0 = i0 - m_begins[0];
645  const size_t j1 = i1 - m_begins[1];
646  const size_t j2 = i2 - m_begins[2];
647  const size_t j3 = i3 - m_begins[3];
648  return m_map.reference(j0,j1,j2,j3);
649  }
650 
651  //------------------------------
652  // Rank 5
653 
654  template< typename I0 , typename I1 , typename I2 , typename I3
655  , typename I4>
656  KOKKOS_FORCEINLINE_FUNCTION
657  typename std::enable_if<
658  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4>::value
659  && ( 5 == Rank )
660  && is_default_map
661  ), reference_type >::type
662  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
663  , const I4 & i4 ) const
664  {
665  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3, i4) )
666  const size_t j0 = i0 - m_begins[0];
667  const size_t j1 = i1 - m_begins[1];
668  const size_t j2 = i2 - m_begins[2];
669  const size_t j3 = i3 - m_begins[3];
670  const size_t j4 = i4 - m_begins[4];
671  return m_map.m_impl_handle[ m_map.m_impl_offset(j0, j1,j2, j3, j4) ];
672  }
673 
674  template< typename I0 , typename I1 , typename I2 , typename I3
675  , typename I4>
676  KOKKOS_FORCEINLINE_FUNCTION
677  typename std::enable_if<
678  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4>::value
679  && ( 5 == Rank )
680  && ! is_default_map
681  ), reference_type >::type
682  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
683  , const I4 & i4) const
684  {
685  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map, m_begins, i0,i1, i2, i3, i4) )
686  const size_t j0 = i0 - m_begins[0];
687  const size_t j1 = i1 - m_begins[1];
688  const size_t j2 = i2 - m_begins[2];
689  const size_t j3 = i3 - m_begins[3];
690  const size_t j4 = i4 - m_begins[4];
691  return m_map.reference(j0,j1,j2,j3,j4);
692  }
693 
694  //------------------------------
695  // Rank 6
696 
697  template< typename I0 , typename I1 , typename I2 , typename I3
698  , typename I4 , typename I5 >
699  KOKKOS_FORCEINLINE_FUNCTION
700  typename std::enable_if<
701  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5>::value
702  && ( 6 == Rank )
703  && is_default_map
704  ), reference_type >::type
705  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
706  , const I4 & i4 , const I5 & i5 ) const
707  {
708  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5) )
709  const size_t j0 = i0 - m_begins[0];
710  const size_t j1 = i1 - m_begins[1];
711  const size_t j2 = i2 - m_begins[2];
712  const size_t j3 = i3 - m_begins[3];
713  const size_t j4 = i4 - m_begins[4];
714  const size_t j5 = i5 - m_begins[5];
715  return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3,j4,j5) ];
716  }
717 
718  template< typename I0 , typename I1 , typename I2 , typename I3
719  , typename I4 , typename I5>
720  KOKKOS_FORCEINLINE_FUNCTION
721  typename std::enable_if<
722  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5>::value
723  && ( 6 == Rank )
724  && ! is_default_map
725  ), reference_type >::type
726  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
727  , const I4 & i4 , const I5 & i5) const
728  {
729  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5) )
730  const size_t j0 = i0 - m_begins[0];
731  const size_t j1 = i1 - m_begins[1];
732  const size_t j2 = i2 - m_begins[2];
733  const size_t j3 = i3 - m_begins[3];
734  const size_t j4 = i4 - m_begins[4];
735  const size_t j5 = i5 - m_begins[5];
736  return m_map.reference(j0,j1,j2,j3,j4,j5);
737  }
738 
739  //------------------------------
740  // Rank 7
741 
742  template< typename I0 , typename I1 , typename I2 , typename I3
743  , typename I4 , typename I5 , typename I6>
744  KOKKOS_FORCEINLINE_FUNCTION
745  typename std::enable_if<
746  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6>::value
747  && ( 7 == Rank )
748  && is_default_map
749  ), reference_type >::type
750  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
751  , const I4 & i4 , const I5 & i5 , const I6 & i6) const
752  {
753  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6) )
754  const size_t j0 = i0 - m_begins[0];
755  const size_t j1 = i1 - m_begins[1];
756  const size_t j2 = i2 - m_begins[2];
757  const size_t j3 = i3 - m_begins[3];
758  const size_t j4 = i4 - m_begins[4];
759  const size_t j5 = i5 - m_begins[5];
760  const size_t j6 = i6 - m_begins[6];
761  return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3,j4,j5,j6) ];
762  }
763 
764  template< typename I0 , typename I1 , typename I2 , typename I3
765  , typename I4 , typename I5 , typename I6 >
766  KOKKOS_FORCEINLINE_FUNCTION
767  typename std::enable_if<
768  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6>::value
769  && ( 7 == Rank )
770  && ! is_default_map
771  ), reference_type >::type
772  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
773  , const I4 & i4 , const I5 & i5 , const I6 & i6) const
774  {
775  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6) )
776  const size_t j0 = i0 - m_begins[0];
777  const size_t j1 = i1 - m_begins[1];
778  const size_t j2 = i2 - m_begins[2];
779  const size_t j3 = i3 - m_begins[3];
780  const size_t j4 = i4 - m_begins[4];
781  const size_t j5 = i5 - m_begins[5];
782  const size_t j6 = i6 - m_begins[6];
783  return m_map.reference(j0,j1,j2,j3,j4,j5,j6);
784  }
785 
786  //------------------------------
787  // Rank 8
788 
789  template< typename I0 , typename I1 , typename I2 , typename I3
790  , typename I4 , typename I5 , typename I6 , typename I7 >
791  KOKKOS_FORCEINLINE_FUNCTION
792  typename std::enable_if<
793  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6,I7>::value
794  && ( 8 == Rank )
795  && is_default_map
796  ), reference_type >::type
797  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
798  , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7) const
799  {
800  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6, i7) )
801  const size_t j0 = i0 - m_begins[0];
802  const size_t j1 = i1 - m_begins[1];
803  const size_t j2 = i2 - m_begins[2];
804  const size_t j3 = i3 - m_begins[3];
805  const size_t j4 = i4 - m_begins[4];
806  const size_t j5 = i5 - m_begins[5];
807  const size_t j6 = i6 - m_begins[6];
808  const size_t j7 = i7 - m_begins[7];
809  return m_map.m_impl_handle[ m_map.m_impl_offset(j0,j1,j2,j3,j4,j5,j6,j7) ];
810  }
811 
812  template< typename I0 , typename I1 , typename I2 , typename I3
813  , typename I4 , typename I5 , typename I6 , typename I7>
814  KOKKOS_FORCEINLINE_FUNCTION
815  typename std::enable_if<
816  ( Kokkos::Impl::are_integral<I0,I1,I2,I3,I4,I5,I6,I7>::value
817  && ( 8 == Rank )
818  && ! is_default_map
819  ), reference_type >::type
820  operator()( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
821  , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7 ) const
822  {
823  KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY( (m_track,m_map,m_begins, i0,i1, i2, i3, i4, i5, i6, i7) )
824  const size_t j0 = i0 - m_begins[0];
825  const size_t j1 = i1 - m_begins[1];
826  const size_t j2 = i2 - m_begins[2];
827  const size_t j3 = i3 - m_begins[3];
828  const size_t j4 = i4 - m_begins[4];
829  const size_t j5 = i5 - m_begins[5];
830  const size_t j6 = i6 - m_begins[6];
831  const size_t j7 = i7 - m_begins[7];
832  return m_map.reference(j0,j1,j2,j3,j4,j5,j6,j7);
833  }
834 
835 
836 #undef KOKKOS_IMPL_OFFSETVIEW_OPERATOR_VERIFY
837 
838  //----------------------------------------
839  // Standard destructor, constructors, and assignment operators
840 
841  KOKKOS_INLINE_FUNCTION
842  ~OffsetView() {}
843 
844  KOKKOS_INLINE_FUNCTION
845  OffsetView() : m_track(), m_map() {
846 
847  for(size_t i = 0; i < Rank; ++i) m_begins[i] = KOKKOS_INVALID_INDEX;
848  }
849 
850  KOKKOS_INLINE_FUNCTION
851  OffsetView( const OffsetView & rhs ) : m_track( rhs.m_track, traits::is_managed ), m_map( rhs.m_map ),
852  m_begins(rhs.m_begins) {}
853 
854  KOKKOS_INLINE_FUNCTION
855  OffsetView( OffsetView && rhs ) : m_track( std::move(rhs.m_track) ),
856  m_map( std::move(rhs.m_map)), m_begins(std::move(rhs.m_begins)) {}
857 
858  KOKKOS_INLINE_FUNCTION
859  OffsetView & operator = ( const OffsetView & rhs ) {
860  m_track = rhs.m_track ;
861  m_map = rhs.m_map ;
862  m_begins = rhs.m_begins;
863  return *this ;
864  }
865 
866  KOKKOS_INLINE_FUNCTION
867  OffsetView & operator = ( OffsetView && rhs ) {
868  m_track = std::move(rhs.m_track) ;
869  m_map = std::move(rhs.m_map) ;
870  m_begins = std::move(rhs.m_begins) ;
871  return *this ;
872  }
873 
874  //interoperability with View
875  private:
876  typedef View< typename traits::scalar_array_type ,
877  typename traits::array_layout ,
878  typename traits::device_type ,
879  typename traits::memory_traits > view_type;
880  public:
881 
882  KOKKOS_INLINE_FUNCTION
883  view_type view() const {
884 
885  view_type v(m_track, m_map);
886  return v ;
887  }
888 
889  template<class RT, class ... RP>
890  KOKKOS_INLINE_FUNCTION
891  OffsetView( const View<RT, RP...> & aview) :
892  m_track(aview.impl_track()), m_map(){
893 
894  typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
895  typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
896  static_assert( Mapping::is_assignable , "Incompatible OffsetView copy construction" );
897  Mapping::assign( m_map , aview.impl_map() , m_track );
898 
899  for (int i = 0; i < aview.Rank; ++i) {
900  m_begins[i] = 0;
901  }
902  }
903 
904  template<class RT, class ... RP>
905  KOKKOS_INLINE_FUNCTION
906  OffsetView( const View<RT, RP...> & aview
907  ,const index_list_type & minIndices) :
908  m_track(aview.impl_track()), m_map(){
909 
910  typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
911  typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
912  static_assert( Mapping::is_assignable , "Incompatible OffsetView copy construction" );
913  Mapping::assign( m_map , aview.impl_map() , m_track );
914 
915 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
916  Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
917 #else
918  Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
919 
920 #endif
921 
922  for (size_t i = 0; i < minIndices.size(); ++i) {
923  m_begins[i] = minIndices.begin()[i];
924  }
925  }
926  template<class RT, class ... RP>
927  KOKKOS_INLINE_FUNCTION
928  OffsetView( const View<RT, RP...> & aview
929  ,const begins_type & beg) :
930  m_track(aview.impl_track()), m_map(), m_begins(beg){
931 
932  typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
933  typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
934  static_assert( Mapping::is_assignable , "Incompatible OffsetView copy construction" );
935  Mapping::assign( m_map , aview.impl_map() , m_track );
936 
937 
938  //#ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
939  // Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
940  //#else
941  // Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
942  //
943  //#endif
944 
945  }
946 
947  // may assign unmanaged from managed.
948 
949 
950  template< class RT , class ... RP >
951  KOKKOS_INLINE_FUNCTION
952  OffsetView( const OffsetView<RT,RP...> & rhs )
953  : m_track( rhs.m_track , traits::is_managed )
954  , m_map()
955  , m_begins(rhs.m_begins)
956  {
957  typedef typename OffsetView<RT,RP...>::traits SrcTraits ;
958  typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
959  static_assert( Mapping::is_assignable , "Incompatible OffsetView copy construction" );
960  Mapping::assign( m_map , rhs.m_map , rhs.m_track ); //swb what about assign?
961  }
962 
963 
964  //----------------------------------------
965  // Allocation tracking properties
966  KOKKOS_INLINE_FUNCTION
967  int use_count() const
968  { return m_track.use_count(); }
969 
970  inline
971  const std::string label() const
972  { return m_track.template get_label< typename traits::memory_space >(); }
973 
974 
975  template< typename Label>
976  explicit inline
977  OffsetView( const Label & arg_label
978  ,typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value , const index_list_type >::type
979  range0
980  ,const index_list_type range1 = KOKKOS_INVALID_INDEX_RANGE
981  ,const index_list_type range2 = KOKKOS_INVALID_INDEX_RANGE
982  ,const index_list_type range3 = KOKKOS_INVALID_INDEX_RANGE
983  ,const index_list_type range4 = KOKKOS_INVALID_INDEX_RANGE
984  ,const index_list_type range5 = KOKKOS_INVALID_INDEX_RANGE
985  ,const index_list_type range6 = KOKKOS_INVALID_INDEX_RANGE
986  ,const index_list_type range7 = KOKKOS_INVALID_INDEX_RANGE
987 
988  ) : OffsetView( Kokkos::Impl::ViewCtorProp< std::string >( arg_label ),
989  typename traits::array_layout
990  ( range0.begin()[1] - range0.begin()[0] + 1, range1.begin()[1] - range1.begin()[0] + 1 ,
991  range2.begin()[1] - range2.begin()[0] + 1, range3.begin()[1] - range3.begin()[0] + 1,
992  range4.begin()[1] - range4.begin()[0] + 1, range5.begin()[1] - range5.begin()[0] + 1 ,
993  range6.begin()[1] - range6.begin()[0] + 1, range7.begin()[1] - range7.begin()[0] + 1 ),
994  {range0.begin()[0], range1.begin()[0], range2.begin()[0], range3.begin()[0], range4.begin()[0],
995  range5.begin()[0], range6.begin()[0], range7.begin()[0] })
996  {
997 
998  }
999 
1000 
1001 
1002  template<class ... P >
1003  explicit KOKKOS_INLINE_FUNCTION
1004  OffsetView( const Kokkos::Impl::ViewCtorProp< P ... > & arg_prop
1005  ,typename std::enable_if< Kokkos::Impl::ViewCtorProp< P... >::has_pointer , typename traits::array_layout >::type const & arg_layout
1006  ,const index_list_type minIndices
1007  )
1008  : m_track() // No memory tracking
1009  , m_map( arg_prop , arg_layout )
1010  {
1011 
1012 
1013  for (size_t i = 0; i < minIndices.size(); ++i) {
1014  m_begins[i] = minIndices.begin()[i];
1015  }
1016  static_assert(
1017  std::is_same< pointer_type
1018  , typename Kokkos::Impl::ViewCtorProp< P... >::pointer_type
1019  >::value ,
1020  "When constructing OffsetView to wrap user memory, you must supply matching pointer type" );
1021  }
1022 
1023  template<class ... P >
1024  explicit inline
1025  OffsetView( const Kokkos::Impl::ViewCtorProp< P ... > & arg_prop
1026  , typename std::enable_if< ! Kokkos::Impl::ViewCtorProp< P... >::has_pointer , typename traits::array_layout>::type const & arg_layout
1027  ,const index_list_type minIndices
1028  )
1029  : m_track()
1030  , m_map()
1031 
1032  {
1033 
1034  for(size_t i = 0; i < Rank; ++i)
1035  m_begins[i] = minIndices.begin()[i];
1036 
1037  // Append layout and spaces if not input
1038  typedef Kokkos::Impl::ViewCtorProp< P ... > alloc_prop_input ;
1039 
1040  // use 'std::integral_constant<unsigned,I>' for non-types
1041  // to avoid duplicate class error.
1042  typedef Kokkos::Impl::ViewCtorProp
1043  < P ..., typename std::conditional < alloc_prop_input::has_label
1044  , std::integral_constant<unsigned,0>, typename std::string >::type
1045  , typename std::conditional
1046  < alloc_prop_input::has_memory_space
1047  , std::integral_constant<unsigned,1>
1048  , typename traits::device_type::memory_space
1049  >::type
1050  , typename std::conditional
1051  < alloc_prop_input::has_execution_space
1052  , std::integral_constant<unsigned,2>
1053  , typename traits::device_type::execution_space
1054  >::type
1055  > alloc_prop ;
1056 
1057  static_assert( traits::is_managed
1058  , "OffsetView allocation constructor requires managed memory" );
1059 
1060  if ( alloc_prop::initialize &&
1061 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
1062  ! alloc_prop::execution_space::is_initialized()
1063 #else
1064  ! alloc_prop::execution_space::impl_is_initialized()
1065 #endif
1066  ) {
1067  // If initializing view data then
1068  // the execution space must be initialized.
1069  Kokkos::Impl::throw_runtime_exception("Constructing OffsetView and initializing data with uninitialized execution space");
1070  }
1071 
1072  // Copy the input allocation properties with possibly defaulted properties
1073  alloc_prop prop_copy( arg_prop );
1074 
1075  //------------------------------------------------------------
1076 #if defined( KOKKOS_ENABLE_CUDA )
1077  // If allocating in CudaUVMSpace must fence before and after
1078  // the allocation to protect against possible concurrent access
1079  // on the CPU and the GPU.
1080  // Fence using the trait's executon space (which will be Kokkos::Cuda)
1081  // to avoid incomplete type errors from usng Kokkos::Cuda directly.
1082  if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
1083  typename traits::device_type::memory_space::execution_space().fence();
1084  }
1085 #endif
1086  //------------------------------------------------------------
1087 
1088  Kokkos::Impl::SharedAllocationRecord<> *
1089  record = m_map.allocate_shared( prop_copy , arg_layout );
1090 
1091  //------------------------------------------------------------
1092 #if defined( KOKKOS_ENABLE_CUDA )
1093  if ( std::is_same< Kokkos::CudaUVMSpace , typename traits::device_type::memory_space >::value ) {
1094  typename traits::device_type::memory_space::execution_space().fence();
1095  }
1096 #endif
1097  //------------------------------------------------------------
1098 
1099  // Setup and initialization complete, start tracking
1100  m_track.assign_allocated_record_to_uninitialized( record );
1101 
1102 #ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
1103  Kokkos::Experimental::Impl::runtime_check_rank_host(traits::rank_dynamic, Rank, minIndices, label());
1104 #else
1105  Kokkos::Experimental::Impl::runtime_check_rank_device(traits::rank_dynamic, Rank, minIndices);
1106 
1107 #endif
1108 
1109  }
1110 
1111 
1112  };
1113 
1114 
1115 
1120  template < typename D , class ... P >
1121  KOKKOS_INLINE_FUNCTION
1122  constexpr unsigned rank( const OffsetView<D , P...> & V ) { return V.Rank; } //Temporary until added to view
1123 
1124  //----------------------------------------------------------------------------
1125  //----------------------------------------------------------------------------
1126  namespace Impl {
1127 
1128  template< class T >
1129  KOKKOS_INLINE_FUNCTION
1130  typename std::enable_if< std::is_integral<T>::value, T>::type
1131  shift_input(const T arg, const int64_t offset)
1132  {
1133  return arg - offset;
1134  }
1135 
1136  KOKKOS_INLINE_FUNCTION
1137  Kokkos::Impl::ALL_t
1138  shift_input(const Kokkos::Impl::ALL_t arg, const int64_t offset)
1139  {
1140  return arg;
1141  }
1142 
1143  template< class T >
1144  KOKKOS_INLINE_FUNCTION
1145  typename std::enable_if< std::is_integral<T>::value, Kokkos::pair<T,T> >::type
1146  shift_input(const Kokkos::pair<T, T> arg, const int64_t offset)
1147  {
1148 
1149  return Kokkos::make_pair<T,T>(arg.first - offset, arg.second - offset);
1150 
1151  }
1152  template< class T >
1153  inline
1154  typename std::enable_if< std::is_integral<T>::value, std::pair<T,T> >::type
1155  shift_input(const std::pair<T, T> arg, const int64_t offset)
1156  {
1157 
1158  return std::make_pair<T,T>(arg.first - offset, arg.second - offset);
1159 
1160  }
1161 
1162  template <size_t N, class Arg, class A>
1163  KOKKOS_INLINE_FUNCTION
1164  void
1165  map_arg_to_new_begin(const size_t i,
1166  Kokkos::Array<int64_t, N> &subviewBegins, typename std::enable_if< N != 0, const Arg>::type shiftedArg,
1167  const Arg arg, const A viewBegins, size_t & counter) {
1168 
1169  if( !std::is_integral<Arg>::value) {
1170  subviewBegins[counter] = shiftedArg == arg ? viewBegins[i] : 0;
1171  counter++;
1172  }
1173  }
1174 
1175  template <size_t N, class Arg, class A>
1176  KOKKOS_INLINE_FUNCTION
1177  void
1178  map_arg_to_new_begin(const size_t i,
1179  Kokkos::Array<int64_t, N> &subviewBegins, typename std::enable_if< N == 0, const Arg>::type shiftedArg,
1180  const Arg arg, const A viewBegins, size_t & counter) {
1181 
1182  }
1183 
1184 
1185  template< class D, class ... P , class T >
1186  KOKKOS_INLINE_FUNCTION
1187  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1188  < void /* deduce subview type from source view traits */
1189  , ViewTraits< D , P... >
1190  , T
1191  >::type >::type
1192  subview_offset(const OffsetView< D, P... > & src, T arg) {
1193 
1194  auto theView = src.view();
1195  auto begins = src.begins();
1196 
1197  T shiftedArg = shift_input(arg, begins[0]);
1198 
1199  constexpr size_t rank = Kokkos::Impl::ViewMapping
1200  < void /* deduce subview type from source view traits */
1201  , ViewTraits< D , P... >
1202  , T>::type::Rank;
1203 
1204  auto theSubview = Kokkos::subview( theView , shiftedArg);
1205 
1206  Kokkos::Array<int64_t, rank> subviewBegins;
1207  size_t counter = 0;
1208  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg, arg, begins, counter);
1209 
1210  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1211  void /* deduce subview type from source view traits */
1212  , ViewTraits< D , P... > , T >::type >::type offsetView(theSubview, subviewBegins);
1213 
1214  return offsetView;
1215 
1216  }
1217 
1218  template< class D, class ... P , class T0, class T1 >
1219  KOKKOS_INLINE_FUNCTION
1220  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1221  < void /* deduce subview type from source view traits */
1222  , ViewTraits< D , P... >
1223  , T0, T1
1224  >::type >::type
1225  subview_offset(const Kokkos::Experimental::OffsetView< D, P... > & src, T0 arg0, T1 arg1) {
1226 
1227  auto theView = src.view();
1228  auto begins = src.begins();
1229 
1230  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1231  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1232 
1233  auto theSubview = Kokkos::subview(theView , shiftedArg0, shiftedArg1);
1234  constexpr size_t rank = Kokkos::Impl::ViewMapping
1235  < void /* deduce subview type from source view traits */
1236  , ViewTraits< D , P... >
1237  , T0, T1>::type::Rank;
1238 
1239  Kokkos::Array<int64_t, rank> subviewBegins;
1240  size_t counter = 0;
1241  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1242  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1243 
1244  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1245  void /* deduce subview type from source view traits */
1246  , ViewTraits< D , P... > , T0, T1 >::type >::type offsetView(theSubview, subviewBegins);
1247 
1248  return offsetView;
1249 
1250  }
1251 
1252  template< class D, class ... P , class T0, class T1, class T2 >
1253  KOKKOS_INLINE_FUNCTION
1254  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1255  < void /* deduce subview type from source view traits */
1256  , ViewTraits< D , P... >
1257  , T0, T1, T2
1258  >::type >::type
1259  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2) {
1260 
1261  auto theView = src.view();
1262  auto begins = src.begins();
1263 
1264  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1265  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1266  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1267 
1268  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2);
1269 
1270  constexpr size_t rank = Kokkos::Impl::ViewMapping
1271  < void /* deduce subview type from source view traits */
1272  , ViewTraits< D , P... >
1273  , T0, T1, T2>::type::Rank;
1274 
1275  Kokkos::Array<int64_t, rank> subviewBegins;
1276 
1277  size_t counter = 0;
1278  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1279  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1280  Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1281 
1282  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1283  void /* deduce subview type from source view traits */
1284  , ViewTraits< D , P... > , T0, T1, T2 >::type >::type offsetView(theSubview, subviewBegins);
1285 
1286  return offsetView;
1287  }
1288 
1289  template< class D, class ... P , class T0, class T1, class T2, class T3 >
1290  KOKKOS_INLINE_FUNCTION
1291  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1292  < void /* deduce subview type from source view traits */
1293  , ViewTraits< D , P... >
1294  , T0, T1, T2, T3
1295  >::type >::type
1296  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
1297 
1298  auto theView = src.view();
1299  auto begins = src.begins();
1300 
1301  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1302  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1303  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1304  T3 shiftedArg3 = shift_input(arg3, begins[3]);
1305 
1306  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3);
1307 
1308  constexpr size_t rank = Kokkos::Impl::ViewMapping
1309  < void /* deduce subview type from source view traits */
1310  , ViewTraits< D , P... >
1311  , T0, T1, T2, T3>::type::Rank;
1312  Kokkos::Array<int64_t, rank> subviewBegins;
1313 
1314  size_t counter = 0;
1315  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1316  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1317  Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1318  Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1319 
1320  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1321  void /* deduce subview type from source view traits */
1322  , ViewTraits< D , P... > , T0, T1, T2, T3 >::type >::type offsetView(theSubview, subviewBegins);
1323 
1324  return offsetView;
1325  }
1326 
1327  template< class D, class ... P , class T0, class T1, class T2, class T3, class T4 >
1328  KOKKOS_INLINE_FUNCTION
1329  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1330  < void /* deduce subview type from source view traits */
1331  , ViewTraits< D , P... >
1332  , T0, T1, T2, T3, T4
1333  >::type >::type
1334  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
1335 
1336  auto theView = src.view();
1337  auto begins = src.begins();
1338 
1339  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1340  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1341  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1342  T3 shiftedArg3 = shift_input(arg3, begins[3]);
1343  T4 shiftedArg4 = shift_input(arg4, begins[4]);
1344 
1345  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4);
1346 
1347  constexpr size_t rank = Kokkos::Impl::ViewMapping
1348  < void /* deduce subview type from source view traits */
1349  , ViewTraits< D , P... >
1350  , T0, T1, T2, T3, T4>::type::Rank;
1351  Kokkos::Array<int64_t, rank> subviewBegins;
1352 
1353  size_t counter = 0;
1354  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1355  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1356  Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1357  Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1358  Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1359 
1360  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1361  void /* deduce subview type from source view traits */
1362  , ViewTraits< D , P... > , T0, T1, T2, T3, T4 >::type >::type offsetView(theSubview, subviewBegins);
1363 
1364  return offsetView;
1365  }
1366 
1367  template< class D, class ... P , class T0, class T1, class T2, class T3, class T4,
1368  class T5 >
1369  KOKKOS_INLINE_FUNCTION
1370  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1371  < void /* deduce subview type from source view traits */
1372  , ViewTraits< D , P... >
1373  , T0, T1, T2, T3, T4, T5
1374  >::type >::type
1375  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
1376 
1377  auto theView = src.view();
1378  auto begins = src.begins();
1379 
1380  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1381  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1382  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1383  T3 shiftedArg3 = shift_input(arg3, begins[3]);
1384  T4 shiftedArg4 = shift_input(arg4, begins[4]);
1385  T5 shiftedArg5 = shift_input(arg5, begins[5]);
1386 
1387  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5);
1388 
1389  constexpr size_t rank = Kokkos::Impl::ViewMapping
1390  < void /* deduce subview type from source view traits */
1391  , ViewTraits< D , P... >
1392  , T0, T1, T2, T3, T4, T5>::type::Rank;
1393 
1394  Kokkos::Array<int64_t, rank> subviewBegins;
1395 
1396  size_t counter = 0;
1397  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1398  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1399  Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1400  Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1401  Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1402  Kokkos::Experimental::Impl::map_arg_to_new_begin(5, subviewBegins, shiftedArg5, arg5, begins, counter);
1403 
1404  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1405  void /* deduce subview type from source view traits */
1406  , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5 >::type >::type offsetView(theSubview, subviewBegins);
1407 
1408  return offsetView;
1409  }
1410  template< class D, class ... P , class T0, class T1, class T2, class T3, class T4,
1411  class T5, class T6>
1412  KOKKOS_INLINE_FUNCTION
1413  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1414  < void /* deduce subview type from source view traits */
1415  , ViewTraits< D , P... >
1416  , T0, T1, T2, T3, T4, T5, T6
1417  >::type >::type
1418  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
1419  T6 arg6) {
1420 
1421  auto theView = src.view();
1422  auto begins = src.begins();
1423 
1424  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1425  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1426  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1427  T3 shiftedArg3 = shift_input(arg3, begins[3]);
1428  T4 shiftedArg4 = shift_input(arg4, begins[4]);
1429  T5 shiftedArg5 = shift_input(arg5, begins[5]);
1430  T6 shiftedArg6 = shift_input(arg6, begins[6]);
1431 
1432  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5,
1433  shiftedArg6);
1434 
1435  constexpr size_t rank = Kokkos::Impl::ViewMapping
1436  < void /* deduce subview type from source view traits */
1437  , ViewTraits< D , P... >
1438  , T0, T1, T2, T3, T4, T5, T6>::type::Rank;
1439 
1440  Kokkos::Array<int64_t, rank> subviewBegins;
1441 
1442  size_t counter = 0;
1443  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1444  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1445  Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1446  Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1447  Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1448  Kokkos::Experimental::Impl::map_arg_to_new_begin(5, subviewBegins, shiftedArg5, arg5, begins, counter);
1449  Kokkos::Experimental::Impl::map_arg_to_new_begin(6, subviewBegins, shiftedArg6, arg6, begins, counter);
1450 
1451  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1452  void /* deduce subview type from source view traits */
1453  , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5,
1454  T6 >::type >::type offsetView(theSubview, subviewBegins);
1455 
1456  return offsetView;
1457  }
1458 
1459  template< class D, class ... P , class T0, class T1, class T2, class T3, class T4,
1460  class T5, class T6, class T7>
1461  KOKKOS_INLINE_FUNCTION
1462  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1463  < void /* deduce subview type from source view traits */
1464  , ViewTraits< D , P... >
1465  , T0, T1, T2, T3, T4, T5, T6, T7
1466  >::type >::type
1467  subview_offset(const OffsetView< D, P... > & src, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
1468  T6 arg6, T7 arg7) {
1469 
1470  auto theView = src.view();
1471  auto begins = src.begins();
1472 
1473  T0 shiftedArg0 = shift_input(arg0, begins[0]);
1474  T1 shiftedArg1 = shift_input(arg1, begins[1]);
1475  T2 shiftedArg2 = shift_input(arg2, begins[2]);
1476  T3 shiftedArg3 = shift_input(arg3, begins[3]);
1477  T4 shiftedArg4 = shift_input(arg4, begins[4]);
1478  T5 shiftedArg5 = shift_input(arg5, begins[5]);
1479  T6 shiftedArg6 = shift_input(arg6, begins[6]);
1480  T7 shiftedArg7 = shift_input(arg7, begins[7]);
1481 
1482  auto theSubview = Kokkos::subview( theView , shiftedArg0, shiftedArg1, shiftedArg2, shiftedArg3, shiftedArg4, shiftedArg5,
1483  shiftedArg6, shiftedArg7);
1484 
1485  constexpr size_t rank = Kokkos::Impl::ViewMapping
1486  < void /* deduce subview type from source view traits */
1487  , ViewTraits< D , P... >
1488  , T0, T1, T2, T3, T4, T5, T6, T7>::type::Rank;
1489 
1490  Kokkos::Array<int64_t, rank> subviewBegins;
1491 
1492  size_t counter = 0;
1493  Kokkos::Experimental::Impl::map_arg_to_new_begin(0, subviewBegins, shiftedArg0, arg0, begins, counter);
1494  Kokkos::Experimental::Impl::map_arg_to_new_begin(1, subviewBegins, shiftedArg1, arg1, begins, counter);
1495  Kokkos::Experimental::Impl::map_arg_to_new_begin(2, subviewBegins, shiftedArg2, arg2, begins, counter);
1496  Kokkos::Experimental::Impl::map_arg_to_new_begin(3, subviewBegins, shiftedArg3, arg3, begins, counter);
1497  Kokkos::Experimental::Impl::map_arg_to_new_begin(4, subviewBegins, shiftedArg4, arg4, begins, counter);
1498  Kokkos::Experimental::Impl::map_arg_to_new_begin(5, subviewBegins, shiftedArg5, arg5, begins, counter);
1499  Kokkos::Experimental::Impl::map_arg_to_new_begin(6, subviewBegins, shiftedArg6, arg6, begins, counter);
1500  Kokkos::Experimental::Impl::map_arg_to_new_begin(7, subviewBegins, shiftedArg7, arg7, begins, counter);
1501 
1502  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping<
1503  void /* deduce subview type from source view traits */
1504  , ViewTraits< D , P... > , T0, T1, T2, T3, T4, T5,
1505  T6, T7 >::type >::type offsetView(theSubview, subviewBegins);
1506 
1507  return offsetView;
1508  }
1509  }
1510 
1511  template< class D, class ... P , class ... Args >
1512  KOKKOS_INLINE_FUNCTION
1513  typename Kokkos::Experimental::Impl::GetOffsetViewTypeFromViewType<typename Kokkos::Impl::ViewMapping
1514  < void /* deduce subview type from source view traits */
1515  , ViewTraits< D , P... >
1516  , Args ...
1517  >::type >::type
1518  subview( const OffsetView< D, P... > & src , Args ... args )
1519  {
1520  static_assert( OffsetView< D , P... >::Rank == sizeof...(Args) ,
1521  "subview requires one argument for each source OffsetView rank" );
1522 
1523 
1524  return Kokkos::Experimental::Impl::subview_offset(src, args...);
1525 
1526 
1527  }
1528 
1529  }
1530 }
1531 //----------------------------------------------------------------------------
1532 //----------------------------------------------------------------------------
1533 
1534 namespace Kokkos {
1535  namespace Experimental {
1536  template< class LT , class ... LP , class RT , class ... RP >
1537  KOKKOS_INLINE_FUNCTION
1538  bool operator == ( const OffsetView<LT,LP...> & lhs ,
1539  const OffsetView<RT,RP...> & rhs )
1540  {
1541  // Same data, layout, dimensions
1542  typedef ViewTraits<LT,LP...> lhs_traits ;
1543  typedef ViewTraits<RT,RP...> rhs_traits ;
1544 
1545  return
1546  std::is_same< typename lhs_traits::const_value_type ,
1547  typename rhs_traits::const_value_type >::value &&
1548  std::is_same< typename lhs_traits::array_layout ,
1549  typename rhs_traits::array_layout >::value &&
1550  std::is_same< typename lhs_traits::memory_space ,
1551  typename rhs_traits::memory_space >::value &&
1552  unsigned(lhs_traits::rank) == unsigned(rhs_traits::rank) &&
1553  lhs.data() == rhs.data() &&
1554  lhs.span() == rhs.span() &&
1555  lhs.extent(0) == rhs.extent(0) &&
1556  lhs.extent(1) == rhs.extent(1) &&
1557  lhs.extent(2) == rhs.extent(2) &&
1558  lhs.extent(3) == rhs.extent(3) &&
1559  lhs.extent(4) == rhs.extent(4) &&
1560  lhs.extent(5) == rhs.extent(5) &&
1561  lhs.extent(6) == rhs.extent(6) &&
1562  lhs.extent(7) == rhs.extent(7) &&
1563  lhs.begin(0) == rhs.begin(0) &&
1564  lhs.begin(1) == rhs.begin(1) &&
1565  lhs.begin(2) == rhs.begin(2) &&
1566  lhs.begin(3) == rhs.begin(3) &&
1567  lhs.begin(4) == rhs.begin(4) &&
1568  lhs.begin(5) == rhs.begin(5) &&
1569  lhs.begin(6) == rhs.begin(6) &&
1570  lhs.begin(7) == rhs.begin(7)
1571  ;
1572  }
1573 
1574  template< class LT , class ... LP , class RT , class ... RP >
1575  KOKKOS_INLINE_FUNCTION
1576  bool operator != ( const OffsetView<LT,LP...> & lhs ,
1577  const OffsetView<RT,RP...> & rhs )
1578  {
1579  return ! ( operator==(lhs,rhs) );
1580  }
1581 
1582  template< class LT , class ... LP , class RT , class ... RP >
1583  KOKKOS_INLINE_FUNCTION
1584  bool operator == ( const View<LT,LP...> & lhs ,
1585  const OffsetView<RT,RP...> & rhs )
1586  {
1587  // Same data, layout, dimensions
1588  typedef ViewTraits<LT,LP...> lhs_traits ;
1589  typedef ViewTraits<RT,RP...> rhs_traits ;
1590 
1591  return
1592  std::is_same< typename lhs_traits::const_value_type ,
1593  typename rhs_traits::const_value_type >::value &&
1594  std::is_same< typename lhs_traits::array_layout ,
1595  typename rhs_traits::array_layout >::value &&
1596  std::is_same< typename lhs_traits::memory_space ,
1597  typename rhs_traits::memory_space >::value &&
1598  unsigned(lhs_traits::rank) == unsigned(rhs_traits::rank) &&
1599  lhs.data() == rhs.data() &&
1600  lhs.span() == rhs.span() &&
1601  lhs.extent(0) == rhs.extent(0) &&
1602  lhs.extent(1) == rhs.extent(1) &&
1603  lhs.extent(2) == rhs.extent(2) &&
1604  lhs.extent(3) == rhs.extent(3) &&
1605  lhs.extent(4) == rhs.extent(4) &&
1606  lhs.extent(5) == rhs.extent(5) &&
1607  lhs.extent(6) == rhs.extent(6) &&
1608  lhs.extent(7) == rhs.extent(7)
1609  ;
1610  }
1611 
1612  template< class LT , class ... LP , class RT , class ... RP >
1613  KOKKOS_INLINE_FUNCTION
1614  bool operator == ( const OffsetView<LT,LP...> & lhs ,
1615  const View<RT,RP...> & rhs )
1616  { return rhs == lhs;}
1617 
1618  }
1619 } /* namespace Kokkos */
1620 
1621 //----------------------------------------------------------------------------
1622 //----------------------------------------------------------------------------
1623 
1624 
1625 namespace Kokkos {
1626  namespace Experimental {
1627  template< class DT , class ... DP >
1628  inline
1629  void deep_copy
1630  ( const OffsetView<DT,DP...> & dst
1631  , typename ViewTraits<DT,DP...>::const_value_type & value
1632  , typename std::enable_if<
1633  std::is_same< typename ViewTraits<DT,DP...>::specialize , void >::value
1634  >::type * = 0 )
1635  {
1636  static_assert(
1637  std::is_same< typename ViewTraits<DT,DP...>::non_const_value_type ,
1638  typename ViewTraits<DT,DP...>::value_type >::value
1639  , "deep_copy requires non-const type" );
1640 
1641  auto dstView = dst.view();
1642  Kokkos::deep_copy( dstView , value );
1643 
1644  }
1645 
1646  template< class DT , class ... DP , class ST , class ... SP >
1647  inline
1648  void deep_copy
1649  ( const OffsetView<DT,DP...> & dst
1650  , const OffsetView<ST,SP...> & value
1651  , typename std::enable_if<
1652  std::is_same< typename ViewTraits<DT,DP...>::specialize , void >::value
1653  >::type * = 0 )
1654  {
1655  static_assert(
1656  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
1657  typename ViewTraits<ST,SP...>::non_const_value_type >::value
1658  , "deep_copy requires matching non-const destination type" );
1659 
1660  auto dstView = dst.view();
1661  Kokkos::deep_copy( dstView , value.view() );
1662 
1663  }
1664  template< class DT , class ... DP , class ST , class ... SP >
1665  inline
1666  void deep_copy
1667  ( const OffsetView<DT,DP...> & dst
1668  , const View<ST,SP...> & value
1669  , typename std::enable_if<
1670  std::is_same< typename ViewTraits<DT,DP...>::specialize , void >::value
1671  >::type * = 0 )
1672  {
1673  static_assert(
1674  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
1675  typename ViewTraits<ST,SP...>::non_const_value_type >::value
1676  , "deep_copy requires matching non-const destination type" );
1677 
1678  auto dstView = dst.view();
1679  Kokkos::deep_copy( dstView , value);
1680 
1681  }
1682 
1683  template< class DT , class ... DP , class ST , class ... SP >
1684  inline
1685  void deep_copy
1686  ( const View<DT,DP...> & dst
1687  , const OffsetView<ST,SP...> & value
1688  , typename std::enable_if<
1689  std::is_same< typename ViewTraits<DT,DP...>::specialize , void >::value
1690  >::type * = 0 )
1691  {
1692  static_assert(
1693  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
1694  typename ViewTraits<ST,SP...>::non_const_value_type >::value
1695  , "deep_copy requires matching non-const destination type" );
1696 
1697  Kokkos::deep_copy( dst , value.view() );
1698 
1699  }
1700  namespace Impl {
1701 
1702  // Deduce Mirror Types
1703  template<class Space, class T, class ... P>
1704  struct MirrorOffsetViewType {
1705  // The incoming view_type
1706  typedef typename Kokkos::Experimental::OffsetView<T,P...> src_view_type;
1707  // The memory space for the mirror view
1708  typedef typename Space::memory_space memory_space;
1709  // Check whether it is the same memory space
1710  enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
1711  // The array_layout
1712  typedef typename src_view_type::array_layout array_layout;
1713  // The data type (we probably want it non-const since otherwise we can't even deep_copy to it.
1714  typedef typename src_view_type::non_const_data_type data_type;
1715  // The destination view type if it is not the same memory space
1716  typedef Kokkos::Experimental::OffsetView<data_type,array_layout,Space> dest_view_type;
1717  // If it is the same memory_space return the existsing view_type
1718  // This will also keep the unmanaged trait if necessary
1719  typedef typename std::conditional<is_same_memspace,src_view_type,dest_view_type>::type view_type;
1720  };
1721 
1722  template<class Space, class T, class ... P>
1723  struct MirrorOffsetType {
1724  // The incoming view_type
1725  typedef typename Kokkos::Experimental::OffsetView<T,P...> src_view_type;
1726  // The memory space for the mirror view
1727  typedef typename Space::memory_space memory_space;
1728  // Check whether it is the same memory space
1729  enum { is_same_memspace = std::is_same<memory_space,typename src_view_type::memory_space>::value };
1730  // The array_layout
1731  typedef typename src_view_type::array_layout array_layout;
1732  // The data type (we probably want it non-const since otherwise we can't even deep_copy to it.
1733  typedef typename src_view_type::non_const_data_type data_type;
1734  // The destination view type if it is not the same memory space
1735  typedef Kokkos::Experimental::OffsetView<data_type,array_layout,Space> view_type;
1736  };
1737 
1738  }
1739 
1740  template< class T , class ... P >
1741  inline
1742  typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror
1743  create_mirror( const Kokkos::Experimental::OffsetView<T,P...> & src
1744  , typename std::enable_if<
1745  ! std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout
1746  , Kokkos::LayoutStride >::value
1747  >::type * = 0
1748  )
1749  {
1750  typedef OffsetView<T,P...> src_type ;
1751  typedef typename src_type::HostMirror dst_type ;
1752 
1753  return dst_type( Kokkos::Impl::ViewCtorProp< std::string >(std::string( src.label() ).append("_mirror") ),
1754  typename Kokkos::ViewTraits<T,P...>::array_layout
1755  ( src.extent(0), src.extent(1), src.extent(2), src.extent(3), src.extent(4),
1756  src.extent(5), src.extent(6), src.extent(7) ),
1757  { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1758  src.begin(5), src.begin(6), src.begin(7) });
1759  }
1760 
1761  template< class T , class ... P >
1762  inline
1763  typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror
1764  create_mirror( const Kokkos::Experimental::OffsetView<T,P...> & src
1765  , typename std::enable_if<
1766  std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout
1767  , Kokkos::LayoutStride >::value
1768  >::type * = 0
1769  )
1770  {
1771  typedef OffsetView<T,P...> src_type ;
1772  typedef typename src_type::HostMirror dst_type ;
1773 
1774  Kokkos::LayoutStride layout ;
1775 
1776  layout.dimension[0] = src.extent(0);
1777  layout.dimension[1] = src.extent(1);
1778  layout.dimension[2] = src.extent(2);
1779  layout.dimension[3] = src.extent(3);
1780  layout.dimension[4] = src.extent(4);
1781  layout.dimension[5] = src.extent(5);
1782  layout.dimension[6] = src.extent(6);
1783  layout.dimension[7] = src.extent(7);
1784 
1785  layout.stride[0] = src.stride_0();
1786  layout.stride[1] = src.stride_1();
1787  layout.stride[2] = src.stride_2();
1788  layout.stride[3] = src.stride_3();
1789  layout.stride[4] = src.stride_4();
1790  layout.stride[5] = src.stride_5();
1791  layout.stride[6] = src.stride_6();
1792  layout.stride[7] = src.stride_7();
1793 
1794  return dst_type( std::string( src.label() ).append("_mirror") , layout,
1795  { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1796  src.begin(5), src.begin(6), src.begin(7) } );
1797  }
1798 
1799 
1800  // Create a mirror in a new space (specialization for different space)
1801  template<class Space, class T, class ... P>
1802  typename Kokkos::Experimental::Impl::MirrorOffsetType<Space,T,P ...>::view_type
1803  create_mirror(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src) {
1804  return typename Kokkos::Experimental::Impl::MirrorOffsetType<Space,T,P ...>::view_type(src.label(),src.layout(),
1805  { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1806  src.begin(5), src.begin(6), src.begin(7) } );
1807  }
1808 
1809 
1810  template< class T , class ... P >
1811  inline
1812  typename Kokkos::Experimental::OffsetView< T, P... >::HostMirror
1813  create_mirror_view( const typename Kokkos::Experimental::OffsetView< T,P... > & src
1814  , typename std::enable_if<(
1815  std::is_same< typename Kokkos::Experimental::OffsetView<T,P...>::memory_space
1816  , typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::memory_space
1817  >::value
1818  &&
1819  std::is_same< typename Kokkos::Experimental::OffsetView<T,P...>::data_type
1820  , typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::data_type
1821  >::value
1822  )>::type * = 0
1823  )
1824  {
1825  return src ;
1826  }
1827 
1828  template< class T , class ... P >
1829  inline
1830  typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror
1831  create_mirror_view( const Kokkos::Experimental::OffsetView<T,P...> & src
1832  , typename std::enable_if< ! (
1833  std::is_same< typename Kokkos::Experimental::OffsetView<T,P...>::memory_space
1834  , typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::memory_space
1835  >::value
1836  &&
1837  std::is_same< typename Kokkos::Experimental::OffsetView<T,P...>::data_type
1838  , typename Kokkos::Experimental::OffsetView<T,P...>::HostMirror::data_type
1839  >::value
1840  )>::type * = 0
1841  )
1842  {
1843  return Kokkos::Experimental::create_mirror( src );
1844  }
1845 
1846  // Create a mirror view in a new space (specialization for same space)
1847  template<class Space, class T, class ... P>
1848  typename Kokkos::Experimental::Impl::MirrorOffsetViewType<Space,T,P ...>::view_type
1849  create_mirror_view(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src
1850  , typename std::enable_if<Impl::MirrorOffsetViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1851  return src;
1852  }
1853 
1854  // Create a mirror view in a new space (specialization for different space)
1855  template<class Space, class T, class ... P>
1856  typename Kokkos::Experimental::Impl::MirrorOffsetViewType<Space,T,P ...>::view_type
1857  create_mirror_view(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src
1858  , typename std::enable_if<!Impl::MirrorOffsetViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1859  return typename Kokkos::Experimental::Impl::MirrorOffsetViewType<Space,T,P ...>::view_type(src.label(),src.layout(),
1860  { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1861  src.begin(5), src.begin(6), src.begin(7) } );
1862  }
1863  //
1864  // // Create a mirror view and deep_copy in a new space (specialization for same space)
1865  // template<class Space, class T, class ... P>
1866  // typename Kokkos::Experimental::Impl::MirrorViewType<Space,T,P ...>::view_type
1867  // create_mirror_view_and_copy(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src
1868  // , std::string const& name = ""
1869  // , typename std::enable_if<Impl::MirrorViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1870  // (void)name;
1871  // return src;
1872  // }
1873  //
1874  // // Create a mirror view and deep_copy in a new space (specialization for different space)
1875  // template<class Space, class T, class ... P>
1876  // typename Kokkos::Experimental::Impl::MirrorViewType<Space,T,P ...>::view_type
1877  // create_mirror_view_and_copy(const Space& , const Kokkos::Experimental::OffsetView<T,P...> & src
1878  // , std::string const& name = ""
1879  // , typename std::enable_if<!Impl::MirrorViewType<Space,T,P ...>::is_same_memspace>::type* = 0 ) {
1880  // using Mirror = typename Kokkos::Experimental::Impl::MirrorViewType<Space,T,P ...>::view_type;
1881  // std::string label = name.empty() ? src.label() : name;
1882  // auto mirror = Mirror(ViewAllocateWithoutInitializing(label), src.layout(),
1883  // { src.begin(0), src.begin(1), src.begin(2), src.begin(3), src.begin(4),
1884  // src.begin(5), src.begin(6), src.begin(7) });
1885  // deep_copy(mirror, src);
1886  // return mirror;
1887  // }
1888 
1889  }
1890 } /* namespace Kokkos */
1891 
1892 
1893 //----------------------------------------------------------------------------
1894 //----------------------------------------------------------------------------
1895 
1896 
1897 #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