Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
KokkosExp_View_MP_Vector_Contiguous.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef KOKKOS_EXPERIMENTAL_VIEW_MP_VECTOR_CONTIGUOUS_HPP
43 #define KOKKOS_EXPERIMENTAL_VIEW_MP_VECTOR_CONTIGUOUS_HPP
44 
45 #include "Sacado_Traits.hpp"
46 #include "Sacado_MP_Vector.hpp"
48 
49 #include "Kokkos_Core.hpp"
50 #include "Kokkos_View_Utils.hpp"
52 
53 #include "impl/KokkosExp_ViewMapping.hpp"
54 
55 //----------------------------------------------------------------------------
56 
57 namespace Kokkos {
58 namespace Experimental {
59 namespace Impl {
60 
62 
63 template< class ... Args >
64 struct is_ViewMPVectorContiguous { enum { value = false }; };
65 
66 template< class D , class ... P , class ... Args >
67 struct is_ViewMPVectorContiguous< Kokkos::View<D,P...> , Args... > {
68  enum { value =
69  std::is_same< typename Kokkos::ViewTraits<D,P...>::specialize
71  &&
72  ( ( sizeof...(Args) == 0 ) ||
73  is_ViewMPVectorContiguous< Args... >::value ) };
74 };
75 
76 } // namespace Impl
77 } // namespace Experimental
78 } // namespace Kokkos
79 
80 namespace Kokkos {
81 
82 template <typename T, typename ... P>
83 struct is_view_mp_vector< View<T,P...> > {
84  typedef View<T,P...> view_type;
85  static const bool value =
86  std::is_same< typename view_type::specialize,
88 };
89 
90 template <typename T, typename ... P>
91 KOKKOS_INLINE_FUNCTION
92 constexpr typename
93 std::enable_if< is_view_mp_vector< View<T,P...> >::value, unsigned >::type
94 dimension_scalar(const View<T,P...>& view) {
95  return view.implementation_map().dimension_scalar();
96 }
97 
98 template <typename D, typename ... P>
99 struct FlatArrayType< View<D,P...>,
100  typename std::enable_if< is_view_mp_vector< View<D,P...> >::value >::type > {
101  typedef View<D,P...> view_type;
102  typedef typename view_type::traits::dimension dimension;
104  typedef typename Kokkos::Experimental::Impl::ViewDataType< flat_value_type , dimension >::type flat_data_type;
105  typedef View<flat_data_type,P...> type;
106 };
107 
108 // Overload of deep_copy for MP::Vector views intializing to a constant scalar
109 template< class DT, class ... DP >
111  const View<DT,DP...> & view ,
112  const typename View<DT,DP...>::array_type::value_type & value
113  , typename std::enable_if<(
114  std::is_same< typename ViewTraits<DT,DP...>::specialize
116  )>::type * = 0 )
117 {
118  static_assert(
119  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
120  typename ViewTraits<DT,DP...>::non_const_value_type >::value
121  , "Can only deep copy into non-const type" );
122 
123  typedef typename FlatArrayType< View<DT,DP...> >::type flat_array_type;
124  Kokkos::Experimental::Impl::ViewFill< flat_array_type >( view , value );
125 }
126 
127 // Overload of deep_copy for MP::Vector views intializing to a constant MP::Vector
128 template< class DT, class ... DP >
130  const View<DT,DP...> & view ,
131  const typename View<DT,DP...>::value_type & value
132  , typename std::enable_if<(
133  std::is_same< typename ViewTraits<DT,DP...>::specialize
135  )>::type * = 0 )
136 {
137  static_assert(
138  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
139  typename ViewTraits<DT,DP...>::non_const_value_type >::value
140  , "Can only deep copy into non-const type" );
141 
142  // static_assert(
143  // Sacado::StaticSize< typename View<DT,DP...>::value_type >::value
144  // ||
145  // std::is_same< Kokkos::Impl::ActiveExecutionMemorySpace
146  // , Kokkos::HostSpace >::value
147  // , "Deep copy from a FAD type must be statically sized or host space" );
148 
149  Kokkos::Experimental::Impl::ViewFill< View<DT,DP...> >( view , value );
150 }
151 
152 /* Specialize for deep copy of MP::Vector */
153 template< class DT , class ... DP , class ST , class ... SP >
154 inline
155 void deep_copy( const View<DT,DP...> & dst ,
156  const View<ST,SP...> & src
157  , typename std::enable_if<(
158  std::is_same< typename ViewTraits<DT,DP...>::specialize
160  &&
161  std::is_same< typename ViewTraits<ST,SP...>::specialize
163  )>::type * = 0 )
164 {
165  static_assert(
166  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
167  typename ViewTraits<DT,DP...>::non_const_value_type >::value
168  , "Deep copy destination must be non-const" );
169 
170  static_assert(
171  ( unsigned(ViewTraits<DT,DP...>::rank) ==
172  unsigned(ViewTraits<ST,SP...>::rank) )
173  , "Deep copy destination and source must have same rank" );
174 
175  // Note ETP 09/29/2016: Use FlatArrayType instead of array_type to work
176  // around issue where dst and src are rank-1, but have differing layouts.
177  // Kokkos' deep_copy() doesn't work in this case because the array_type
178  // will be rank-2. It should be possible to make deep_copy() work there,
179  // but this seems easier.
180 
181  // Kokkos::deep_copy(
182  // typename View<DT,DP...>::array_type( dst ) ,
183  // typename View<ST,SP...>::array_type( src ) );
184 
186  typename FlatArrayType< View<DT,DP...> >::type( dst ) ,
187  typename FlatArrayType< View<ST,SP...> >::type( src ) );
188 }
189 
190 } // namespace Kokkos
191 
192 //----------------------------------------------------------------------------
193 
194 namespace Kokkos {
195 namespace Experimental {
196 namespace Impl {
197 
198 template< class DataType , class ArrayLayout , typename StorageType >
199 struct ViewDataAnalysis< DataType /* Original view data type */
200  , ArrayLayout
201  , Sacado::MP::Vector< StorageType > >
202 {
203 private:
204 
206  typedef ViewArrayAnalysis< DataType > array_analysis ;
207  static const int DimVector = StorageType::static_size;
208 
209 public:
210 
211  // Specialized view data mapping:
213 
214  typedef typename array_analysis::dimension dimension ;
216  typedef typename array_analysis::const_value_type const_value_type ;
217  typedef typename array_analysis::non_const_value_type non_const_value_type ;
218 
219  // Generate analogous multidimensional array specification type.
220  typedef typename
221  ViewDataType< value_type , dimension >::type type ;
222  typedef typename
223  ViewDataType< const_value_type , dimension >::type const_type ;
224  typedef typename
225  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
226 
227 private:
228 
229  // A const ?
230  enum { is_const = std::is_same< value_type , const_value_type >::value };
231 
232  // The unwrapped scalar types:
233  typedef typename
234  std::conditional< is_const , const ScalarType , ScalarType >::type
236 
239 
240  // Prepend or append the vector dimension based on ArrayLayout
241  // Note: you can't prepend a static dimension, so use 0 for LayoutLeft
242  typedef typename array_analysis::dimension::
243  template prepend<0>::type
245  typedef typename array_analysis::dimension::
246  template append<DimVector>::type
248  typedef typename std::conditional<
249  std::is_same< ArrayLayout, Kokkos::LayoutLeft>::value,
252 
253 public:
254 
255  // Generate "flattened" multidimensional array specification type.
256  typedef typename
257  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
258 
259  typedef typename
260  ViewDataType< const_scalar_type , scalar_dimension >::type
262 
263  typedef typename
264  ViewDataType< non_const_scalar_type , scalar_dimension >::type
266 };
267 
268 } // namespace Impl
269 } // namespace Experimental
270 } // namespace Kokkos
271 
272 //----------------------------------------------------------------------------
273 
274 namespace Kokkos {
275 namespace Experimental {
276 namespace Impl {
277 
278  template < class ValueType,
279  bool is_static = Sacado::IsStaticallySized<ValueType>::value >
281 
282 // MP::Vector allocation for statically-sized MP::Vector types.
283 // In this case we can reinterpret cast directly between pointers of types
284 // MP::Vector<Storage> and MP::Vector<Storage>::value_type.
285 template <class ValueType>
286 struct MPVectorAllocation<ValueType, true> {
287  typedef ValueType value_type;
288  typedef typename Sacado::ValueType<value_type>::type scalar_type;
289 
292 
293  KOKKOS_INLINE_FUNCTION
294  static constexpr size_t
295  memory_span(const size_t span, const unsigned vector_size) {
296  return span * vector_size * sizeof(scalar_type);
297  }
298 
299  KOKKOS_INLINE_FUNCTION
300  MPVectorAllocation() : value_ptr(0), scalar_ptr(0) {}
301 
302  template <typename T>
303  KOKKOS_INLINE_FUNCTION
305  value_ptr = a.value_ptr;
306  scalar_ptr = a.scalar_ptr;
307  return *this;
308  }
309 
310  KOKKOS_INLINE_FUNCTION
311  void set(value_type* ptr, const size_t span, const unsigned vector_size) {
312  value_ptr = ptr;
313  scalar_ptr = reinterpret_cast<scalar_type*>(ptr);
314  }
315 
316  template <class ExecSpace>
317  struct ConstructDestructFunctor {
318  typedef ViewValueFunctor< ExecSpace, scalar_type > FunctorType ;
321 
322  ConstructDestructFunctor() = default;
323  ConstructDestructFunctor(const ConstructDestructFunctor&) = default;
324  ConstructDestructFunctor& operator=(const ConstructDestructFunctor&) = default;
325 
326  ConstructDestructFunctor(const ExecSpace & space,
327  const bool initialize,
328  const size_t span,
329  const unsigned vector_size,
330  scalar_type* scalar_ptr) :
331  m_functor( space , scalar_ptr , span*vector_size ),
332  m_initialize(initialize) {}
333 
335  if (m_initialize)
336  m_functor.construct_shared_allocation();
337  }
338 
340  if (m_initialize)
341  m_functor.destroy_shared_allocation();
342  }
343 
344  };
345 
346  template <class ExecSpace>
347  inline ConstructDestructFunctor<ExecSpace>
348  create_functor(const ExecSpace & space,
349  const bool initialize,
350  const size_t span,
351  const unsigned vector_size) const {
352  return ConstructDestructFunctor<ExecSpace>(space, initialize, span, vector_size, scalar_ptr);
353  }
354 
355  // Assign scalar_type pointer to give ptr
356  template <typename T>
357  void assign(T * ptr) {
358  value_ptr = reinterpret_cast<value_type*>(ptr);
359  scalar_ptr = reinterpret_cast<scalar_type*>(ptr);
360  }
361 
362 };
363 
364 // MP::Vector allocation for dynamically-sized MP::Vector types.
365 // In this case we allocate two chunks of data, the first for the the
366 // MP::Vector<Storage> itself and then for the underlying scalar type
367 // (MP::Vector<Storage>::value_type). The memory is laid out with the
368 // former followed by the latter.
369 template <class ValueType>
370 struct MPVectorAllocation<ValueType, false> {
371  typedef ValueType value_type;
372  typedef typename Sacado::ValueType<value_type>::type scalar_type;
373 
376 
377  KOKKOS_INLINE_FUNCTION
378  static constexpr size_t
379  memory_span(const size_t span, const unsigned vector_size) {
380  return span * ( vector_size * sizeof(scalar_type) + sizeof(value_type) );
381  }
382 
383  KOKKOS_INLINE_FUNCTION
384  MPVectorAllocation() : value_ptr(0), scalar_ptr(0) {}
385 
386  template <typename T>
387  KOKKOS_INLINE_FUNCTION
389  value_ptr = a.value_ptr;
390  scalar_ptr = a.scalar_ptr;
391  return *this;
392  }
393 
394  // We are making an assumption the data is laid out as described above,
395  // which in general may not be true if the view is created from memory
396  // allocated elsewhere. We should check for that.
397  KOKKOS_INLINE_FUNCTION
398  void set(value_type* ptr, const size_t span, const unsigned vector_size) {
399  value_ptr = ptr;
400  scalar_ptr = reinterpret_cast<scalar_type*>(ptr+span);
401  }
402 
403  template <class ExecSpace>
404  struct VectorConstruct {
405  ExecSpace m_space;
408  size_t m_span;
409  unsigned m_vector_size;
410 
411  VectorConstruct() = default;
412  VectorConstruct(const VectorConstruct&) = default;
413  VectorConstruct& operator=(const VectorConstruct&) = default;
414 
415  inline
416  VectorConstruct(const ExecSpace& space,
417  value_type* p,
418  scalar_type* sp,
419  const size_t span,
420  const unsigned vector_size) :
421  m_space(space), m_p(p), m_sp(sp), m_span(span), m_vector_size(vector_size) {}
422 
423  inline void execute() {
424  if ( ! m_space.in_parallel() ) {
425  typedef Kokkos::RangePolicy< ExecSpace > PolicyType ;
426  const Kokkos::Impl::ParallelFor< VectorConstruct , PolicyType >
427  closure( *this , PolicyType( 0 , m_span ) );
428  closure.execute();
429  m_space.fence();
430  }
431  else {
432  for ( size_t i = 0 ; i < m_span ; ++i ) operator()(i);
433  }
434  }
435 
436  KOKKOS_INLINE_FUNCTION
437  void operator() (const size_t i) const {
438  new (m_p+i) value_type(m_vector_size, m_sp+i*m_vector_size, false);
439  }
440  };
441 
442  template <class ExecSpace>
443  struct ConstructDestructFunctor {
444  typedef ViewValueFunctor< ExecSpace, scalar_type > ScalarFunctorType ;
445  typedef VectorConstruct< ExecSpace > VectorFunctorType ;
449 
450  ConstructDestructFunctor() = default;
451  ConstructDestructFunctor(const ConstructDestructFunctor&) = default;
452  ConstructDestructFunctor& operator=(const ConstructDestructFunctor&) = default;
453 
454  ConstructDestructFunctor(const ExecSpace & space,
455  const bool initialize,
456  const size_t span,
457  const unsigned vector_size,
458  scalar_type* scalar_ptr,
459  value_type* value_ptr) :
460  m_scalar_functor( space , scalar_ptr , span*vector_size ),
461  m_vector_functor( space , value_ptr , scalar_ptr , span , vector_size ),
462  m_initialize(initialize) {}
463 
465  // First initialize the scalar_type array
466  if (m_initialize)
467  m_scalar_functor.construct_shared_allocation();
468 
469  // Construct each MP::Vector using memory in scalar_ptr array,
470  // setting pointer to MP::Vector values from values array
471  // Equivalent to:
472  // value_type* p = value_ptr;
473  // scalar_type* sp = scalar_ptr;
474  // for (size_t i=0; i<span; ++i) {
475  // new (p++) value_type(vector_size, sp, false);
476  // sp += vector_size;
477  // }
478  // (we always need to do this, regardless of initialization)
479  m_vector_functor.execute();
480  }
481 
483  // We only need to (possibly) call the destructor on values in the
484  // scalar_type array, since the value_type array is a view into it
485  if (m_initialize)
486  m_scalar_functor.destroy_shared_allocation();
487  }
488 
489  };
490 
491  template <class ExecSpace>
492  inline ConstructDestructFunctor<ExecSpace>
493  create_functor(const ExecSpace & space,
494  const bool initialize,
495  const size_t span,
496  const unsigned vector_size) const {
497  return ConstructDestructFunctor<ExecSpace>(space, initialize, span, vector_size, scalar_ptr, value_ptr);
498  }
499 
500  // Assign scalar_type pointer to give ptr
501  // This makes BIG assumption on how the data was allocated
502  template <typename T>
503  void assign(T * ptr) {
504  value_ptr = reinterpret_cast<value_type*>(ptr);
505  if (ptr != 0)
506  scalar_ptr = value_ptr->coeff();
507  else
508  scalar_ptr = 0;
509  }
510 };
511 
512 template< class Traits >
513 class ViewMapping< Traits , /* View internal mapping */
514  typename std::enable_if<
515  ( std::is_same< typename Traits::specialize
516  , ViewMPVectorContiguous >::value
517  &&
518  ( std::is_same< typename Traits::array_layout
519  , Kokkos::LayoutLeft >::value
520  ||
521  std::is_same< typename Traits::array_layout
522  , Kokkos::LayoutRight >::value
523  ||
524  std::is_same< typename Traits::array_layout
525  , Kokkos::LayoutStride >::value
526  )
527  )>::type >
528 {
529 private:
530 
531  template< class , class ... > friend class ViewMapping ;
532  template< class , class ... > friend class Kokkos::Experimental::View ;
533 
537  typedef typename
538  std::add_const< intrinsic_scalar_type >::type const_intrinsic_scalar_type ;
539 
540  enum { StokhosStorageStaticDimension = stokhos_storage_type::static_size };
541  typedef Sacado::integral_nonzero< unsigned , StokhosStorageStaticDimension > sacado_size_type;
542 
544 
545  typedef ViewOffset< typename Traits::dimension
546  , typename Traits::array_layout
547  , void
549 
550  // Prepend or append the vector dimension based on array_layout
551  // Note: you can't prepend a static dimension, so use 0 for LayoutLeft
552  typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
553  typedef typename array_analysis::dimension array_dimension;
554  typedef ViewOffset< typename array_dimension::
555  template append<StokhosStorageStaticDimension>::type,
556  typename Traits::array_layout,
557  void
559  typedef ViewOffset< typename array_dimension::
560  template prepend<0>::type,
561  typename Traits::array_layout,
562  void
564  typedef typename std::conditional<
565  std::is_same< typename Traits::array_layout, Kokkos::LayoutLeft>::value,
568 
571  unsigned m_stride ;
572  sacado_size_type m_sacado_size ; // Size of sacado dimension
573 
574  // Note: if the view is partitioned, m_sacado_size is not the stride in
575  // memory between consecutive MP::Vector entries for given vector index:
576  //
577  // original_sacado_size = m_stride * m_sacado_size
578  // m_stride = 1 for original allocation.
579  //
580  // Stride here has a slightly different meaning than in the standard
581  // View implementation. For the moment we are assuming no padding within
582  // the view array itself and stride is to allow for partitioning the view
583  // by dividing up the scalar type.
584  //
585  // I suspect we could combine this with the way the stride is managed in
586  // the default view, in which case, I don't think we even need a
587  // specialization
588  //
589  // For reshaping by folding the sacado dimension into its next adjacent
590  // dimension, padding wouldn't generally work. So unless there becomes
591  // a way to turn padding off in the default view, a specialization
592  // will be necessary.
593 
594 public:
595 
596  //----------------------------------------
597  // Domain dimensions
598 
599  enum { Rank = Traits::dimension::rank };
600 
601  // Rank corresponding to the sacado dimension
602  enum { Sacado_Rank = std::is_same< typename Traits::array_layout, Kokkos::LayoutLeft >::value ? 0 : Rank+1 };
603 
604  // Using the internal offset mapping so limit to public rank:
605  template< typename iType >
606  KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
607  { return m_offset.m_dim.extent(r); }
608 
609  KOKKOS_INLINE_FUNCTION constexpr
610  typename Traits::array_layout layout() const
611  { return m_offset.layout(); }
612 
613  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
614  { return m_offset.dimension_0(); }
615  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
616  { return m_offset.dimension_1(); }
617  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
618  { return m_offset.dimension_2(); }
619  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
620  { return m_offset.dimension_3(); }
621  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
622  { return m_offset.dimension_4(); }
623  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
624  { return m_offset.dimension_5(); }
625  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
626  { return m_offset.dimension_6(); }
627  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
628  { return m_offset.dimension_7(); }
629 
630  // Is a regular layout with uniform striding for each index.
631  // Since we all for striding within the data type, we can't guarantee
632  // regular striding
633  using is_regular = std::false_type ;
634 
635  // FIXME: Adjust these for m_stride
636  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const
637  { return m_offset.stride_0(); }
638  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const
639  { return m_offset.stride_1(); }
640  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const
641  { return m_offset.stride_2(); }
642  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const
643  { return m_offset.stride_3(); }
644  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const
645  { return m_offset.stride_4(); }
646  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const
647  { return m_offset.stride_5(); }
648  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const
649  { return m_offset.stride_6(); }
650  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const
651  { return m_offset.stride_7(); }
652 
653  template< typename iType >
654  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const
655  { m_offset.stride(s); }
656 
657  // Size of sacado scalar dimension
658  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
659  { return m_sacado_size.value; }
660 
661  // Whether the storage type is statically sized
662  static const bool is_static = stokhos_storage_type::is_static ;
663 
664  // Whether sacado dimension is contiguous
665  static const bool is_contiguous = true;
666 
667  //----------------------------------------
668  // Range of mapping
669 
670  // Return type of reference operators
672 
675 
677  KOKKOS_INLINE_FUNCTION constexpr size_t span() const
678  { return m_offset.span(); }
679 
681  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
682  { return m_offset.span_is_contiguous() && (m_stride == 1); }
683 
685  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
686  { return m_handle.value_ptr ; }
687 
688  //----------------------------------------
689 
690  KOKKOS_FORCEINLINE_FUNCTION
692  { return *m_handle.value_ptr; }
693 
694  // FIXME: Check this
695  template< typename I0 >
696  KOKKOS_FORCEINLINE_FUNCTION
697  typename
698  std::enable_if< std::is_integral<I0>::value &&
699  ! std::is_same< typename Traits::array_layout , Kokkos::LayoutStride >::value
700  , reference_type >::type
701  reference( const I0 & i0 ) const
702  { return m_handle.value_ptr[m_stride * i0]; }
703 
704  // FIXME: Check this
705  template< typename I0 >
706  KOKKOS_FORCEINLINE_FUNCTION
707  typename
708  std::enable_if< std::is_integral<I0>::value &&
709  std::is_same< typename Traits::array_layout , Kokkos::LayoutStride >::value
710  , reference_type >::type
711  reference( const I0 & i0 ) const
712  { return m_handle.value_ptr[ m_stride * m_offset(i0) ]; }
713 
714  template< typename I0 , typename I1 >
715  KOKKOS_FORCEINLINE_FUNCTION
716  reference_type reference( const I0 & i0 , const I1 & i1 ) const
717  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1) ]; }
718 
719  template< typename I0 , typename I1 , typename I2 >
720  KOKKOS_FORCEINLINE_FUNCTION
721  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
722  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1,i2) ]; }
723 
724  template< typename I0 , typename I1 , typename I2 , typename I3 >
725  KOKKOS_FORCEINLINE_FUNCTION
726  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
727  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1,i2,i3) ]; }
728 
729  template< typename I0 , typename I1 , typename I2 , typename I3
730  , typename I4 >
731  KOKKOS_FORCEINLINE_FUNCTION
732  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
733  , const I4 & i4 ) const
734  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1,i2,i3,i4) ]; }
735 
736  template< typename I0 , typename I1 , typename I2 , typename I3
737  , typename I4 , typename I5 >
738  KOKKOS_FORCEINLINE_FUNCTION
739  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
740  , const I4 & i4 , const I5 & i5 ) const
741  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1,i2,i3,i4,i5) ]; }
742 
743  template< typename I0 , typename I1 , typename I2 , typename I3
744  , typename I4 , typename I5 , typename I6 >
745  KOKKOS_FORCEINLINE_FUNCTION
746  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
747  , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
748  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1,i2,i3,i4,i5,i6) ]; }
749 
750  template< typename I0 , typename I1 , typename I2 , typename I3
751  , typename I4 , typename I5 , typename I6 , typename I7 >
752  KOKKOS_FORCEINLINE_FUNCTION
753  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
754  , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7 ) const
755  { return m_handle.value_ptr[ m_stride * m_offset(i0,i1,i2,i3,i4,i5,i6,i7) ]; }
756 
757  //----------------------------------------
758 
760  KOKKOS_INLINE_FUNCTION
761  static size_t memory_span( typename Traits::array_layout const & layout )
762  {
763  // Do not introduce padding...
764  typedef std::integral_constant< unsigned , 0 > padding ;
765  offset_type offset( padding(), layout );
766  sacado_size_type sacado_size =
768  return handle_type::memory_span( offset.span(), sacado_size.value );
769  }
770 
771  //----------------------------------------
772 
773  KOKKOS_INLINE_FUNCTION ~ViewMapping() = default ;
774  KOKKOS_INLINE_FUNCTION ViewMapping() :
775  m_handle(),
776  m_offset(),
777  m_stride(1),
778  m_sacado_size(0)
779  {}
780 
781  KOKKOS_INLINE_FUNCTION ViewMapping( const ViewMapping & ) = default ;
782  KOKKOS_INLINE_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
783 
784  KOKKOS_INLINE_FUNCTION ViewMapping( ViewMapping && ) = default ;
785  KOKKOS_INLINE_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
786 
787  template< class ... P >
788  KOKKOS_INLINE_FUNCTION
789  ViewMapping
790  ( ViewCtorProp< P ... > const & prop
791  , typename Traits::array_layout const & layout
792  )
793  : m_handle()
794  , m_offset( std::integral_constant< unsigned , 0 >()
795  , layout )
796  , m_stride( 1 )
797  , m_sacado_size( Kokkos::Impl::GetSacadoSize<unsigned(Rank)>::eval(layout) )
798  {
799  m_handle.set( ( (ViewCtorProp<void,pointer_type> const &) prop ).value,
800  m_offset.span(), m_sacado_size.value );
801  }
802 
803  //----------------------------------------
804  /* Allocate and construct mapped array.
805  * Allocate via shared allocation record and
806  * return that record for allocation tracking.
807  */
808  template< class ... P >
809  SharedAllocationRecord<> *
810  allocate_shared( ViewCtorProp< P... > const & prop
811  , typename Traits::array_layout const & layout )
812  {
813  typedef ViewCtorProp< P... > ctor_prop ;
814 
816  typedef typename Traits::memory_space memory_space ;
817  typedef typename handle_type::template ConstructDestructFunctor<execution_space> functor_type ;
818  typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
819 
820  // Disallow padding
821  typedef std::integral_constant< unsigned , 0 > padding ;
822 
823  m_offset = offset_type( padding(), layout );
824  m_stride = 1;
826 
827  const size_t alloc_size =
828  handle_type::memory_span( m_offset.span(), m_sacado_size.value );
829 
830  // Create shared memory tracking record with allocate memory from the memory space
831  record_type * const record =
832  record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
833  , ( (ViewCtorProp<void,std::string> const &) prop ).value
834  , alloc_size );
835 
836  // Only set the the pointer and initialize if the allocation is non-zero.
837  // May be zero if one of the dimensions is zero.
838  if ( alloc_size ) {
839 
840  m_handle.set( reinterpret_cast< pointer_type >( record->data() ),
841  m_offset.span(), m_sacado_size.value );
842 
843  // Assume destruction is only required when construction is requested.
844  // The ViewValueFunctor has both value construction and destruction operators.
845  record->m_destroy = m_handle.create_functor(
846  ( (ViewCtorProp<void,execution_space> const &) prop).value
847  , ctor_prop::initialize
848  , m_offset.span()
849  , m_sacado_size.value );
850 
851  // Construct values
852  record->m_destroy.construct_shared_allocation();
853  }
854 
855  return record ;
856  }
857 
858  //----------------------------------------
859  // If the View is to construct or destroy the elements.
860 
861  /*
862  template< class ExecSpace >
863  void construct( const ExecSpace & space ) const
864  {
865  m_handle.construct( space, m_offset.span(), m_sacado_size.value );
866  }
867 
868  template< class ExecSpace >
869  void destroy( const ExecSpace & space ) const
870  {
871  m_handle.destruct( space, m_offset.span(), m_sacado_size.value );
872  }
873  */
874 };
875 
876 } // namespace Impl
877 } // namespace Experimental
878 } // namespace Kokkos
879 
880 //----------------------------------------------------------------------------
881 
882 namespace Kokkos {
883 namespace Experimental {
884 namespace Impl {
885 
890 template< class DstTraits , class SrcTraits >
891 class ViewMapping< DstTraits , SrcTraits ,
892  typename std::enable_if<(
893  std::is_same< typename DstTraits::memory_space
894  , typename SrcTraits::memory_space >::value
895  &&
896  // Destination view has MP::Vector
897  std::is_same< typename DstTraits::specialize
898  , ViewMPVectorContiguous >::value
899  &&
900  // Source view has MP::Vector only
901  std::is_same< typename SrcTraits::specialize
902  , ViewMPVectorContiguous >::value
903  )>::type >
904 {
905 public:
906 
907  enum { is_assignable = true };
908 
909  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
910  typedef ViewMapping< DstTraits , void > DstType ;
911  typedef ViewMapping< SrcTraits , void > SrcType ;
912 
913  KOKKOS_INLINE_FUNCTION static
914  void assign( DstType & dst
915  , const SrcType & src
916  , const TrackType & )
917  {
918  static_assert(
919  (
920  std::is_same< typename DstTraits::array_layout
921  , Kokkos::LayoutLeft >::value ||
922  std::is_same< typename DstTraits::array_layout
923  , Kokkos::LayoutRight >::value ||
924  std::is_same< typename DstTraits::array_layout
925  , Kokkos::LayoutStride >::value
926  )
927  &&
928  (
929  std::is_same< typename SrcTraits::array_layout
930  , Kokkos::LayoutLeft >::value ||
931  std::is_same< typename SrcTraits::array_layout
932  , Kokkos::LayoutRight >::value ||
933  std::is_same< typename SrcTraits::array_layout
934  , Kokkos::LayoutStride >::value
935  )
936  , "View of MP::Vector requires LayoutLeft, LayoutRight, or LayoutStride" );
937 
938  static_assert(
939  std::is_same< typename DstTraits::array_layout
940  , typename SrcTraits::array_layout >::value ||
941  std::is_same< typename DstTraits::array_layout
942  , Kokkos::LayoutStride >::value ||
943  ( unsigned(DstTraits::rank) == 1 && unsigned(SrcTraits::rank) == 1 ) ,
944  "View assignment must have compatible layout" );
945 
946  static_assert(
947  std::is_same< typename DstTraits::value_type
948  , typename SrcTraits::value_type >::value ||
949  std::is_same< typename DstTraits::value_type
950  , typename SrcTraits::const_value_type >::value ,
951  "View assignment must have same value type or const = non-const" );
952 
953  static_assert(
954  ViewDimensionAssignable
955  < typename DstType::offset_type::dimension_type
956  , typename SrcType::offset_type::dimension_type >::value ,
957  "View assignment must have compatible dimensions" );
958 
959  dst.m_handle = src.m_handle ;
960  dst.m_offset = src.m_offset ;
961  dst.m_stride = src.m_stride ;
962  dst.m_sacado_size = src.m_sacado_size ;
963  }
964 };
965 
971 template< class DstTraits , class SrcTraits >
972 class ViewMapping< DstTraits , SrcTraits ,
973  typename std::enable_if<(
974  std::is_same< typename DstTraits::memory_space
975  , typename SrcTraits::memory_space >::value
976  &&
977  // Destination view has ordinary
978  std::is_same< typename DstTraits::specialize , void >::value
979  &&
980  // Source view has MP::Vector only
981  std::is_same< typename SrcTraits::specialize
982  , ViewMPVectorContiguous >::value
983  &&
984  // Ranks match
985  unsigned(DstTraits::dimension::rank) == unsigned(SrcTraits::dimension::rank)+1
986  )>::type >
987 {
988 public:
989 
990  enum { is_assignable = true };
991 
992  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
993  typedef ViewMapping< DstTraits , void > DstType ;
994  typedef ViewMapping< SrcTraits , void > SrcType ;
995 
996  KOKKOS_INLINE_FUNCTION static
997  void assign( DstType & dst
998  , const SrcType & src
999  , const TrackType & )
1000  {
1001  static_assert(
1002  (
1003  std::is_same< typename DstTraits::array_layout
1004  , Kokkos::LayoutLeft >::value ||
1005  std::is_same< typename DstTraits::array_layout
1006  , Kokkos::LayoutRight >::value ||
1007  std::is_same< typename DstTraits::array_layout
1008  , Kokkos::LayoutStride >::value
1009  )
1010  &&
1011  (
1012  std::is_same< typename SrcTraits::array_layout
1013  , Kokkos::LayoutLeft >::value ||
1014  std::is_same< typename SrcTraits::array_layout
1015  , Kokkos::LayoutRight >::value ||
1016  std::is_same< typename SrcTraits::array_layout
1017  , Kokkos::LayoutStride >::value
1018  )
1019  , "View of MP::Vector requires LayoutLeft, LayoutRight, or LayoutStride" );
1020 
1021  static_assert(
1022  std::is_same< typename DstTraits::array_layout
1023  , typename SrcTraits::array_layout >::value ||
1024  std::is_same< typename DstTraits::array_layout
1025  , Kokkos::LayoutStride >::value ,
1026  "View assignment must have compatible layout" );
1027 
1028  static_assert(
1029  std::is_same< typename DstTraits::scalar_array_type
1030  , typename SrcTraits::scalar_array_type >::value ||
1031  std::is_same< typename DstTraits::scalar_array_type
1032  , typename SrcTraits::const_scalar_array_type >::value ,
1033  "View assignment must have same value type or const = non-const" );
1034 
1035  static_assert(
1036  ViewDimensionAssignable<
1037  typename DstType::offset_type::dimension_type,
1038  typename SrcType::array_offset_type::dimension_type >::value,
1039  "View assignment must have compatible dimensions" );
1040 
1041  if ( src.m_stride != 1 ) {
1042  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::MP::Vector ... > cannot assign with non-unit stride ******\n\n");
1043  }
1044 
1045  unsigned dims[8];
1046  dims[0] = src.m_offset.dimension_0();
1047  dims[1] = src.m_offset.dimension_1();
1048  dims[2] = src.m_offset.dimension_2();
1049  dims[3] = src.m_offset.dimension_3();
1050  dims[4] = src.m_offset.dimension_4();
1051  dims[5] = src.m_offset.dimension_5();
1052  dims[6] = src.m_offset.dimension_6();
1053  dims[7] = src.m_offset.dimension_7();
1054  unsigned rank = SrcTraits::dimension::rank;
1055  unsigned sacado_size = src.m_sacado_size.value;
1056  if (std::is_same<typename SrcTraits::array_layout, LayoutLeft>::value) {
1057  // Move sacado_size to the first dimension, shift all others up one
1058  for (unsigned i=rank; i>0; --i)
1059  dims[i] = dims[i-1];
1060  dims[0] = sacado_size;
1061  }
1062  else {
1063  dims[rank] = sacado_size;
1064  }
1065  typedef typename DstType::offset_type dst_offset_type;
1066  dst.m_offset = dst_offset_type( std::integral_constant< unsigned , 0 >(),
1067  typename DstTraits::array_layout(
1068  dims[0] , dims[1] , dims[2] , dims[3] ,
1069  dims[4] , dims[5] , dims[6] , dims[7] ) );
1070  dst.m_handle = src.m_handle.scalar_ptr ;
1071  }
1072 };
1073 
1080 template< class DstTraits , class SrcTraits >
1081 class ViewMapping< DstTraits , SrcTraits ,
1082  typename std::enable_if<(
1083  std::is_same< typename DstTraits::memory_space
1084  , typename SrcTraits::memory_space >::value
1085  &&
1086  // Destination view has ordinary
1087  std::is_same< typename DstTraits::specialize , void >::value
1088  &&
1089  // Source view has MP::Vector only
1090  std::is_same< typename SrcTraits::specialize
1091  , ViewMPVectorContiguous >::value
1092  &&
1093  // Ranks match
1094  unsigned(DstTraits::dimension::rank) == unsigned(SrcTraits::dimension::rank)
1095  )>::type >
1096 {
1097 public:
1098 
1099  enum { is_assignable = true };
1100 
1101  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
1102  typedef ViewMapping< DstTraits , void > DstType ;
1103  typedef ViewMapping< SrcTraits , void > SrcType ;
1104 
1105  KOKKOS_INLINE_FUNCTION static
1106  void assign( DstType & dst
1107  , const SrcType & src
1108  , const TrackType & )
1109  {
1110  static_assert(
1111  (
1112  std::is_same< typename DstTraits::array_layout
1113  , Kokkos::LayoutLeft >::value ||
1114  std::is_same< typename DstTraits::array_layout
1115  , Kokkos::LayoutRight >::value ||
1116  std::is_same< typename DstTraits::array_layout
1117  , Kokkos::LayoutStride >::value
1118  )
1119  &&
1120  (
1121  std::is_same< typename SrcTraits::array_layout
1122  , Kokkos::LayoutLeft >::value ||
1123  std::is_same< typename SrcTraits::array_layout
1124  , Kokkos::LayoutRight >::value ||
1125  std::is_same< typename SrcTraits::array_layout
1126  , Kokkos::LayoutStride >::value
1127  )
1128  , "View of MP::Vector requires LayoutLeft, LayoutRight, or LayoutStride" );
1129 
1130  static_assert(
1131  std::is_same< typename DstTraits::array_layout
1132  , typename SrcTraits::array_layout >::value ||
1133  std::is_same< typename DstTraits::array_layout
1134  , Kokkos::LayoutStride >::value ,
1135  "View assignment must have compatible layout" );
1136 
1137  static_assert(
1138  std::is_same< typename DstTraits::value_type
1139  , typename SrcTraits::non_const_value_type::value_type >::value ||
1140  std::is_same< typename DstTraits::value_type
1141  , const typename SrcTraits::non_const_value_type::value_type >::value ,
1142  "View assignment must have same value type or const = non-const" );
1143 
1144  static_assert(
1145  ViewDimensionAssignable<
1146  typename DstType::offset_type::dimension_type,
1147  typename SrcType::offset_type::dimension_type >::value,
1148  "View assignment must have compatible dimensions" );
1149 
1150  if ( src.m_stride != 1 ) {
1151  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::MP::Vector ... > cannot assign with non-unit stride ******\n\n");
1152  }
1153 
1154  unsigned dims[8];
1155  dims[0] = src.m_offset.dimension_0();
1156  dims[1] = src.m_offset.dimension_1();
1157  dims[2] = src.m_offset.dimension_2();
1158  dims[3] = src.m_offset.dimension_3();
1159  dims[4] = src.m_offset.dimension_4();
1160  dims[5] = src.m_offset.dimension_5();
1161  dims[6] = src.m_offset.dimension_6();
1162  dims[7] = src.m_offset.dimension_7();
1163  unsigned rank = SrcTraits::dimension::rank;
1164  unsigned sacado_size = src.m_sacado_size.value;
1165  if (std::is_same<typename DstTraits::array_layout, LayoutLeft>::value) {
1166  dims[0] = dims[0]*sacado_size;
1167  dims[rank] = 0;
1168  }
1169  else {
1170  dims[rank-1] = dims[rank-1]*sacado_size;
1171  dims[rank] = 0;
1172  }
1173  typedef typename DstType::offset_type dst_offset_type;
1174  dst.m_offset = dst_offset_type( std::integral_constant< unsigned , 0 >(),
1175  typename DstTraits::array_layout(
1176  dims[0] , dims[1] , dims[2] , dims[3] ,
1177  dims[4] , dims[5] , dims[6] , dims[7] ) );
1178  dst.m_handle = src.m_handle.scalar_ptr ;
1179  }
1180 };
1181 
1182 } // namespace Impl
1183 } // namespace Experimental
1184 } // namespace Kokkos
1185 
1186 //----------------------------------------------------------------------------
1187 
1188 namespace Kokkos {
1189 namespace Experimental {
1190 namespace Impl {
1191 
1192 // Subview mapping
1193 
1194 template< class DataType, class ... P , class Arg0, class ... Args >
1195 struct ViewMapping
1196  < typename std::enable_if<(
1197  // Source view has MP::Vector only
1198  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::specialize
1199  , ViewMPVectorContiguous >::value
1200  &&
1201  (
1202  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::array_layout
1203  , Kokkos::LayoutLeft >::value ||
1204  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::array_layout
1205  , Kokkos::LayoutRight >::value ||
1206  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::array_layout
1207  , Kokkos::LayoutStride >::value
1208  )
1209  && !Sacado::MP::is_vector_partition<Arg0>::value
1210  )>::type
1211  , Kokkos::Experimental::ViewTraits<DataType,P...>
1212  , Arg0, Args ... >
1213 {
1214 private:
1215 
1216  typedef Kokkos::Experimental::ViewTraits<DataType,P...> SrcTraits;
1217 
1218  //static_assert( SrcTraits::rank == sizeof...(Args) , "" );
1219 
1220  enum
1221  { RZ = false
1222  , R0 = bool(is_integral_extent<0,Arg0,Args...>::value)
1223  , R1 = bool(is_integral_extent<1,Arg0,Args...>::value)
1224  , R2 = bool(is_integral_extent<2,Arg0,Args...>::value)
1225  , R3 = bool(is_integral_extent<3,Arg0,Args...>::value)
1226  , R4 = bool(is_integral_extent<4,Arg0,Args...>::value)
1227  , R5 = bool(is_integral_extent<5,Arg0,Args...>::value)
1228  , R6 = bool(is_integral_extent<6,Arg0,Args...>::value)
1229  };
1230 
1231  // Public rank
1232  enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
1233  + unsigned(R4) + unsigned(R5) + unsigned(R6) };
1234 
1235  // Whether right-most non-MP::Vector rank is a range.
1236  enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
1237  1 == SrcTraits::rank ? R0 : (
1238  2 == SrcTraits::rank ? R1 : (
1239  3 == SrcTraits::rank ? R2 : (
1240  4 == SrcTraits::rank ? R3 : (
1241  5 == SrcTraits::rank ? R4 : (
1242  6 == SrcTraits::rank ? R5 : R6 ))))))) };
1243 
1244  // Subview's layout
1245  typedef typename std::conditional<
1246  ( /* Same array layout IF */
1247  ( rank == 0 ) /* output rank zero */
1248  ||
1249  // OutputRank 1 or 2, InputLayout Left, Interval 0
1250  // because single stride one or second index has a stride.
1251  ( rank <= 2 && R0 && std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutLeft >::value )
1252  ||
1253  // OutputRank 1 or 2, InputLayout Right, Interval [InputRank-1]
1254  // because single stride one or second index has a stride.
1255  ( rank <= 2 && R0_rev && std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutRight >::value )
1256  ), typename SrcTraits::array_layout , Kokkos::LayoutStride
1258 
1260 
1261  typedef typename std::conditional< rank == 0 , sacado_mp_vector_type ,
1262  typename std::conditional< rank == 1 , sacado_mp_vector_type * ,
1263  typename std::conditional< rank == 2 , sacado_mp_vector_type ** ,
1264  typename std::conditional< rank == 3 , sacado_mp_vector_type *** ,
1265  typename std::conditional< rank == 4 , sacado_mp_vector_type **** ,
1266  typename std::conditional< rank == 5 , sacado_mp_vector_type ***** ,
1267  typename std::conditional< rank == 6 , sacado_mp_vector_type ****** ,
1268  sacado_mp_vector_type *******
1271 
1272 public:
1273 
1274  typedef Kokkos::Experimental::ViewTraits
1275  < data_type
1276  , array_layout
1277  , typename SrcTraits::device_type
1278  , typename SrcTraits::memory_traits > traits_type ;
1279 
1280  typedef Kokkos::Experimental::View
1281  < data_type
1282  , array_layout
1283  , typename SrcTraits::device_type
1284  , typename SrcTraits::memory_traits > type ;
1285 
1286 
1287  // The presumed type is 'ViewMapping< traits_type , void >'
1288  // However, a compatible ViewMapping is acceptable.
1289  template< class DstTraits >
1290  KOKKOS_INLINE_FUNCTION
1291  static void assign( ViewMapping< DstTraits , void > & dst
1292  , ViewMapping< SrcTraits , void > const & src
1293  , Arg0 arg0, Args ... args )
1294  {
1295  static_assert(
1296  ViewMapping< DstTraits , traits_type , void >::is_assignable ,
1297  "Subview destination type must be compatible with subview derived type" );
1298 
1299  typedef ViewMapping< DstTraits , void > DstType ;
1300  typedef typename DstType::offset_type dst_offset_type ;
1301 
1302  const SubviewExtents< SrcTraits::rank , rank >
1303  extents( src.m_offset.m_dim , arg0 , args... );
1304 
1305  const size_t offset = src.m_offset( extents.domain_offset(0)
1306  , extents.domain_offset(1)
1307  , extents.domain_offset(2)
1308  , extents.domain_offset(3)
1309  , extents.domain_offset(4)
1310  , extents.domain_offset(5)
1311  , extents.domain_offset(6)
1312  , extents.domain_offset(7) );
1313 
1314  dst.m_offset = dst_offset_type( src.m_offset , extents );
1315  dst.m_handle.value_ptr = src.m_handle.value_ptr + offset;
1316  dst.m_handle.scalar_ptr =
1317  src.m_handle.scalar_ptr + offset * src.m_stride * src.m_sacado_size.value;
1318  dst.m_stride = src.m_stride;
1319  dst.m_sacado_size = src.m_sacado_size;
1320  }
1321 
1322 };
1323 
1324 } // namespace Impl
1325 } // namespace Experimental
1326 } // namespace Kokkos
1327 
1328 //----------------------------------------------------------------------------
1329 //----------------------------------------------------------------------------
1330 //----------------------------------------------------------------------------
1331 
1332 namespace Kokkos {
1333 namespace Experimental {
1334 namespace Impl {
1335 
1336 // Partition mapping
1337 
1338 template< class DataType, class ...P, unsigned Size >
1339 class ViewMapping<
1340  void,
1341  ViewTraits<DataType,P...> ,
1342  Sacado::MP::VectorPartition<Size> >
1343 {
1344 public:
1345 
1346  enum { is_assignable = true };
1347 
1348  typedef ViewTraits<DataType,P...> src_traits;
1349  typedef ViewMapping< src_traits , void > src_type ;
1350 
1351  typedef typename src_type::offset_type::dimension_type src_dimension;
1354  typedef typename storage_type::template apply_N<Size> storage_apply;
1355  typedef typename storage_apply::type strided_storage_type;
1357  typedef typename
1358  ViewDataType< strided_value_type , src_dimension >::type strided_data_type;
1359  typedef ViewTraits<strided_data_type,P...> dst_traits;
1360  typedef View<strided_data_type,P...> type;
1361  typedef ViewMapping< dst_traits , void > dst_type ;
1362 
1363  KOKKOS_INLINE_FUNCTION static
1364  void assign( dst_type & dst
1365  , const src_type & src
1366  , const Sacado::MP::VectorPartition<Size> & part )
1367  {
1368  // The pointer assignments below are not sufficient for dynamically sized
1369  // scalar types, so disallow this case for now
1370  static_assert( storage_type::is_static,
1371  "For performance reasons, partitioned assignment is only implemented for statically-sized MP::Vector types" );
1372 
1373  unsigned len = part.end - part.begin;
1374  if ( Size != len || Size == 0 ) {
1375  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::MP::Vector ... > Invalid size in partitioned view assignment ******\n\n");
1376  }
1377 
1378  dst.m_handle.value_ptr =
1379  reinterpret_cast<strided_value_type*>( src.m_handle.value_ptr ) +
1380  part.begin / len ;
1381  dst.m_handle.scalar_ptr = src.m_handle.scalar_ptr +
1382  (part.begin / len) * src.m_stride * src.m_sacado_size.value ;
1383  dst.m_offset = src.m_offset ;
1384  dst.m_stride = src.m_stride * src.m_sacado_size.value / Size ;
1385  dst.m_sacado_size = len ;
1386  }
1387 };
1388 
1389 } // namespace Impl
1390 } // namespace Experimental
1391 
1392 template< unsigned Size, typename D, typename ... P >
1393 KOKKOS_INLINE_FUNCTION
1394 typename Kokkos::Experimental::Impl::ViewMapping< void, typename Kokkos::Experimental::ViewTraits<D,P...>, Sacado::MP::VectorPartition<Size> >::type
1395 partition( const Kokkos::Experimental::View<D,P...> & src ,
1396  const unsigned beg )
1397 {
1398  typedef Kokkos::Experimental::ViewTraits<D,P...> traits;
1399  typedef typename Kokkos::Experimental::Impl::ViewMapping< void, traits, Sacado::MP::VectorPartition<Size> >::type DstViewType;
1400  const Sacado::MP::VectorPartition<Size> part( beg , beg+Size );
1401  return DstViewType(src, part);
1402 }
1403 
1404 } // namespace Kokkos
1405 
1406 //----------------------------------------------------------------------------
1407 //----------------------------------------------------------------------------
1408 //----------------------------------------------------------------------------
1409 
1410 namespace Kokkos {
1411 namespace Impl {
1412 
1413 // Specialization for deep_copy( view, view::value_type ) for Cuda
1414 #if defined( KOKKOS_HAVE_CUDA )
1415 template< class OutputView >
1416 struct ViewFill< OutputView ,
1417  typename std::enable_if< std::is_same< typename OutputView::specialize,
1418  Experimental::Impl::ViewMPVectorContiguous >::value &&
1419  std::is_same< typename OutputView::execution_space,
1420  Cuda >::value >::type >
1421 {
1422  typedef typename OutputView::const_value_type const_value_type ;
1423  typedef typename OutputView::execution_space execution_space ;
1424  typedef typename OutputView::size_type size_type ;
1425 
1426  template <unsigned VectorLength>
1427  struct Kernel {
1428  typedef typename OutputView::execution_space execution_space ;
1429  const OutputView output;
1430  const_value_type input;
1431 
1432  Kernel( const OutputView & arg_out , const_value_type & arg_in ) :
1433  output(arg_out), input(arg_in) {}
1434 
1435  typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ;
1436 
1437  KOKKOS_INLINE_FUNCTION
1438  void operator()( const team_member & dev ) const
1439  {
1440  const size_type tidx = dev.team_rank() % VectorLength;
1441  const size_type tidy = dev.team_rank() / VectorLength;
1442  const size_type nrow = dev.team_size() / VectorLength;
1443  const size_type nvec = dimension_scalar(output);
1444 
1445  const size_type i0 = dev.league_rank() * nrow + tidy;
1446  if ( i0 >= output.dimension_0() ) return;
1447 
1448  for ( size_type i1 = 0 ; i1 < output.dimension_1() ; ++i1 ) {
1449  for ( size_type i2 = 0 ; i2 < output.dimension_2() ; ++i2 ) {
1450  for ( size_type i3 = 0 ; i3 < output.dimension_3() ; ++i3 ) {
1451  for ( size_type i4 = 0 ; i4 < output.dimension_4() ; ++i4 ) {
1452  for ( size_type i5 = 0 ; i5 < output.dimension_5() ; ++i5 ) {
1453  for ( size_type i6 = 0 ; i6 < output.dimension_6() ; ++i6 ) {
1454  for ( size_type i7 = 0 ; i7 < output.dimension_7() ; ++i7 ) {
1455  for ( size_type is = tidx ; is < nvec ; is+=VectorLength ) {
1456  output(i0,i1,i2,i3,i4,i5,i6,i7).fastAccessCoeff(is) =
1457  input.fastAccessCoeff(is) ;
1458  }}}}}}}}
1459  }
1460  };
1461 
1462  ViewFill( const OutputView & output , const_value_type & input )
1463  {
1464  if ( Sacado::is_constant(input) ) {
1465  deep_copy( output , input.fastAccessCoeff(0) );
1466  }
1467  else {
1468 
1469  // Coalesced accesses are 128 bytes in size
1471  const unsigned vector_length =
1472  ( 128 + sizeof(scalar_type)-1 ) / sizeof(scalar_type);
1473 
1474  // 8 warps per block should give good occupancy
1475  const size_type block_size = 256;
1476 
1477  const size_type rows_per_block = block_size / vector_length;
1478  const size_type n = output.dimension_0();
1479  const size_type league_size = ( n + rows_per_block-1 ) / rows_per_block;
1480  const size_type team_size = rows_per_block * vector_length;
1481  Kokkos::TeamPolicy< execution_space > config( league_size, team_size );
1482 
1483  parallel_for( config, Kernel<vector_length>(output, input) );
1484  execution_space::fence();
1485  }
1486  }
1487 
1488 };
1489 #endif /* #if defined( KOKKOS_HAVE_CUDA ) */
1490 
1491 } // namespace Impl
1492 } // namespace Kokkos
1493 
1494 //----------------------------------------------------------------------------
1495 //----------------------------------------------------------------------------
1496 //----------------------------------------------------------------------------
1497 
1498 namespace Kokkos {
1499 namespace Experimental {
1500 namespace Impl {
1501 
1502 struct ViewSpecializeSacadoFad;
1503 
1510 template< class DstTraits , class SrcTraits >
1511 class ViewMapping< DstTraits , SrcTraits ,
1512  typename std::enable_if<(
1513  std::is_same< typename DstTraits::memory_space
1514  , typename SrcTraits::memory_space >::value
1515  &&
1516  // Destination view has MP::Vector only
1517  std::is_same< typename DstTraits::specialize
1518  , ViewMPVectorContiguous >::value
1519  &&
1520  // Source view has FAD only
1521  std::is_same< typename SrcTraits::specialize
1522  , ViewSpecializeSacadoFad >::value
1523  )>::type >
1524 {
1525 public:
1526 
1527  enum { is_assignable = true };
1528 
1529  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
1530  typedef ViewMapping< DstTraits , void > DstType ;
1531  typedef ViewMapping< SrcTraits , void > SrcFadType ;
1532 
1533  template< class DstType >
1534  KOKKOS_INLINE_FUNCTION static
1535  void assign( DstType & dst
1536  , const SrcFadType & src
1537  , const TrackType & )
1538  {
1539  static_assert(
1540  (
1541  std::is_same< typename DstTraits::array_layout
1542  , Kokkos::LayoutLeft >::value ||
1543  std::is_same< typename DstTraits::array_layout
1544  , Kokkos::LayoutRight >::value ||
1545  std::is_same< typename DstTraits::array_layout
1546  , Kokkos::LayoutStride >::value
1547  )
1548  &&
1549  (
1550  std::is_same< typename SrcTraits::array_layout
1551  , Kokkos::LayoutLeft >::value ||
1552  std::is_same< typename SrcTraits::array_layout
1553  , Kokkos::LayoutRight >::value ||
1554  std::is_same< typename SrcTraits::array_layout
1555  , Kokkos::LayoutStride >::value
1556  )
1557  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1558 
1559  static_assert(
1560  std::is_same< typename DstTraits::array_layout
1561  , typename SrcTraits::array_layout >::value ||
1562  std::is_same< typename DstTraits::array_layout
1563  , Kokkos::LayoutStride >::value ,
1564  "View assignment must have compatible layout" );
1565 
1566  static_assert(
1567  std::is_same< typename DstTraits::data_type
1568  , typename SrcTraits::scalar_array_type >::value ||
1569  std::is_same< typename DstTraits::data_type
1570  , typename SrcTraits::const_scalar_array_type >::value ,
1571  "View assignment must have same value type or const = non-const" );
1572 
1573  static_assert(
1574  ViewDimensionAssignable
1575  < typename DstType::offset_type::dimension_type
1576  , typename SrcFadType::offset_type::dimension_type >::value ,
1577  "View assignment must have compatible dimensions" );
1578 
1579  typedef typename DstType::offset_type dst_offset_type ;
1580 
1581  dst.m_offset = dst_offset_type( src.m_offset );
1582  dst.m_handle.assign(src.m_handle) ;
1583  dst.m_stride = 1;
1584 
1585  // Don't need to set dst.m_sacado_size since it is determined statically
1586  static_assert( DstType::is_static,
1587  "Destination view must be statically allocated" );
1588  }
1589 };
1590 
1591 } // namespace Impl
1592 } // namespace Experimental
1593 } // namespace Kokkos
1594 
1595 //----------------------------------------------------------------------------
1596 //----------------------------------------------------------------------------
1597 //----------------------------------------------------------------------------
1598 
1599 #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_MP_VECTOR_CONTIGUOUS_HPP */
KOKKOS_INLINE_FUNCTION MPVectorAllocation & operator=(const MPVectorAllocation< T, true > &a)
Stokhos::StandardStorage< int, double > storage_type
static KOKKOS_INLINE_FUNCTION constexpr size_t memory_span(const size_t span, const unsigned vector_size)
KOKKOS_INLINE_FUNCTION MPVectorAllocation & operator=(const MPVectorAllocation< T, false > &a)
Kokkos::DefaultExecutionSpace execution_space
ConstructDestructFunctor< ExecSpace > create_functor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned vector_size) const
VectorConstruct(const ExecSpace &space, value_type *p, scalar_type *sp, const size_t span, const unsigned vector_size)
static KOKKOS_INLINE_FUNCTION void assign(dst_type &dst, const src_type &src, const Sacado::MP::VectorPartition< Size > &part)
static KOKKOS_INLINE_FUNCTION constexpr size_t memory_span(const size_t span, const unsigned vector_size)
std::conditional< std::is_same< ArrayLayout, Kokkos::LayoutLeft >::value, prepend_scalar_dimension, append_scalar_dimension >::type scalar_dimension
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< View< T, P... > >::value, unsigned >::type dimension_scalar(const View< T, P... > &view)
KOKKOS_INLINE_FUNCTION bool is_constant(const T &x)
void deep_copy(const Stokhos::CrsMatrix< ValueType, DstDevice, Layout > &dst, const Stokhos::CrsMatrix< ValueType, SrcDevice, Layout > &src)
KOKKOS_INLINE_FUNCTION Kokkos::Experimental::Impl::ViewMapping< void, typename Kokkos::Experimental::ViewTraits< D, P... >, Sacado::MP::VectorPartition< Size > >::type partition(const Kokkos::Experimental::View< D, P... > &src, const unsigned beg)
ConstructDestructFunctor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned vector_size, scalar_type *scalar_ptr, value_type *value_ptr)
ConstructDestructFunctor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned vector_size, scalar_type *scalar_ptr)
std::conditional< rank==0, sacado_mp_vector_type, typename std::conditional< rank==1, sacado_mp_vector_type *, typename std::conditional< rank==2, sacado_mp_vector_type **, typename std::conditional< rank==3, sacado_mp_vector_type ***, typename std::conditional< rank==4, sacado_mp_vector_type ****, typename std::conditional< rank==5, sacado_mp_vector_type *****, typename std::conditional< rank==6, sacado_mp_vector_type ******, sacado_mp_vector_type *******>::type >::type >::type >::type >::type >::type >::type data_type
ConstructDestructFunctor< ExecSpace > create_functor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned vector_size) const