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 // Only include forward declarations so any overloads appear before they
46 // might be used inside Kokkos
48 // We are hooking into Kokkos Core internals here
49 // Need to define this macro since we include non-public headers
50 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
51 #define KOKKOS_IMPL_PUBLIC_INCLUDE
52 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_CORE
53 #endif
54 #include "Kokkos_Layout.hpp"
55 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_CORE
56 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
57 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_CORE
58 #endif
59 
60 #include "Kokkos_View_Utils.hpp"
62 
63 //----------------------------------------------------------------------------
64 
65 namespace Kokkos {
66 namespace Experimental {
67 namespace Impl {
68 
70 
71 template< class ... Args >
72 struct is_ViewMPVectorContiguous { enum { value = false }; };
73 
74 template< class D , class ... P , class ... Args >
75 struct is_ViewMPVectorContiguous< Kokkos::View<D,P...> , Args... > {
76  enum { value =
77  std::is_same< typename Kokkos::ViewTraits<D,P...>::specialize
79  &&
80  ( ( sizeof...(Args) == 0 ) ||
81  is_ViewMPVectorContiguous< Args... >::value ) };
82 };
83 
84 } // namespace Impl
85 } // namespace Experimental
86 } // namespace Kokkos
87 
88 namespace Kokkos {
89 
90 template <typename T, typename ... P>
91 struct is_view_mp_vector< View<T,P...> > {
92  typedef View<T,P...> view_type;
93  static const bool value =
94  std::is_same< typename view_type::specialize,
96 };
97 
98 template <typename T, typename ... P>
99 KOKKOS_INLINE_FUNCTION
100 constexpr typename
101 std::enable_if< is_view_mp_vector< View<T,P...> >::value, unsigned >::type
102 dimension_scalar(const View<T,P...>& view) {
103  return view.impl_map().dimension_scalar();
104 }
105 
106 } // namespace Kokkos
107 
108 //----------------------------------------------------------------------------
109 
110 #include "Sacado_Traits.hpp"
111 #include "Sacado_MP_Vector.hpp"
113 #include "Kokkos_Core.hpp"
114 
115 namespace Kokkos {
116 
117 template <typename D, typename ... P>
118 struct FlatArrayType< View<D,P...>,
119  typename std::enable_if< is_view_mp_vector< View<D,P...> >::value >::type > {
120  typedef View<D,P...> view_type;
121  typedef typename view_type::traits::dimension dimension;
123  typedef typename Kokkos::Impl::ViewDataType< flat_value_type , dimension >::type flat_data_type;
124  typedef View<flat_data_type,P...> type;
125 };
126 
127 template< class T , class ... P >
128 inline
129 typename std::enable_if<
130  std::is_same< typename ViewTraits<T,P...>::specialize ,
132  !std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
133  Kokkos::LayoutStride >::value,
134  typename Kokkos::View<T,P...>::HostMirror>::type
135 create_mirror(const Kokkos::View<T,P...> & src)
136 {
137  typedef View<T,P...> src_type ;
138  typedef typename src_type::HostMirror dst_type ;
139 
140  typename src_type::array_layout layout = src.layout();
141  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
142 
143  return dst_type(std::string(src.label()).append("_mirror"), layout);
144 }
145 
146 template< class T , class ... P >
147 inline
148 typename std::enable_if<
149  std::is_same< typename ViewTraits<T,P...>::specialize ,
151  std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
152  Kokkos::LayoutStride >::value,
153  typename Kokkos::View<T,P...>::HostMirror>::type
154 create_mirror(const Kokkos::View<T,P...> & src)
155 {
156  typedef View<T,P...> src_type ;
157  typedef typename src_type::HostMirror dst_type ;
158 
159  Kokkos::LayoutStride layout ;
160 
161  layout.dimension[0] = src.extent(0);
162  layout.dimension[1] = src.extent(1);
163  layout.dimension[2] = src.extent(2);
164  layout.dimension[3] = src.extent(3);
165  layout.dimension[4] = src.extent(4);
166  layout.dimension[5] = src.extent(5);
167  layout.dimension[6] = src.extent(6);
168  layout.dimension[7] = src.extent(7);
169 
170  layout.stride[0] = src.stride_0();
171  layout.stride[1] = src.stride_1();
172  layout.stride[2] = src.stride_2();
173  layout.stride[3] = src.stride_3();
174  layout.stride[4] = src.stride_4();
175  layout.stride[5] = src.stride_5();
176  layout.stride[6] = src.stride_6();
177  layout.stride[7] = src.stride_7();
178 
179  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
180 
181  return dst_type(std::string(src.label()).append("_mirror"), layout);
182 }
183 
184 template<class Space, class T, class ... P, typename Enabled>
185 typename std::enable_if<
186  std::is_same< typename ViewTraits<T,P...>::specialize ,
188  typename Impl::MirrorType<Space,T,P ...>::view_type>::type
189 create_mirror(const Space& , const Kokkos::View<T,P...> & src)
190 {
191  typedef View<T,P...> src_type ;
192  typename src_type::array_layout layout = src.layout();
193  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
194  return typename Impl::MirrorType<Space,T,P ...>::view_type(src.label(),layout);
195 }
196 
197 template< class T , class ... P >
198 inline
199 typename std::enable_if<
200  std::is_same< typename ViewTraits<T,P...>::specialize ,
202  !std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
203  Kokkos::LayoutStride >::value,
204  typename Kokkos::View<T,P...>::HostMirror>::type
205 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
206  const Kokkos::View<T,P...> & src)
207 {
208  typedef View<T,P...> src_type ;
209  typedef typename src_type::HostMirror dst_type ;
210 
211  typename src_type::array_layout layout = src.layout();
212  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
213 
214  return dst_type(
215  Kokkos::view_alloc(std::string(src.label()).append("_mirror"), wi), layout);
216 }
217 
218 template< class T , class ... P >
219 inline
220 typename std::enable_if<
221  std::is_same< typename ViewTraits<T,P...>::specialize ,
223  std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
224  Kokkos::LayoutStride >::value,
225  typename Kokkos::View<T,P...>::HostMirror>::type
226 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
227  const Kokkos::View<T,P...> & src)
228 {
229  typedef View<T,P...> src_type ;
230  typedef typename src_type::HostMirror dst_type ;
231 
232  Kokkos::LayoutStride layout ;
233 
234  layout.dimension[0] = src.extent(0);
235  layout.dimension[1] = src.extent(1);
236  layout.dimension[2] = src.extent(2);
237  layout.dimension[3] = src.extent(3);
238  layout.dimension[4] = src.extent(4);
239  layout.dimension[5] = src.extent(5);
240  layout.dimension[6] = src.extent(6);
241  layout.dimension[7] = src.extent(7);
242 
243  layout.stride[0] = src.stride_0();
244  layout.stride[1] = src.stride_1();
245  layout.stride[2] = src.stride_2();
246  layout.stride[3] = src.stride_3();
247  layout.stride[4] = src.stride_4();
248  layout.stride[5] = src.stride_5();
249  layout.stride[6] = src.stride_6();
250  layout.stride[7] = src.stride_7();
251 
252  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
253 
254  return dst_type(
255  Kokkos::view_alloc(std::string(src.label()).append("_mirror"), wi), layout);
256 }
257 
258 template<class Space, class T, class ... P, typename Enable>
259 typename std::enable_if<
260  std::is_same< typename ViewTraits<T,P...>::specialize ,
262  typename Impl::MirrorType<Space,T,P ...>::view_type>::type
263 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
264  const Space&, const Kokkos::View<T,P...> & src)
265 {
266  typedef View<T,P...> src_type ;
267  typename src_type::array_layout layout = src.layout();
268  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
270  Kokkos::view_alloc(src.label(), wi), layout);
271 }
272 
273 template <class Space, class T, class... P>
274 typename Impl::MirrorViewType<Space, T, P...>::view_type
276  const Space&, const Kokkos::View<T, P...>& src,
277  std::string const& name,
278  typename std::enable_if<
279  std::is_same<typename ViewTraits<T, P...>::specialize,
282 {
283  (void)name;
284  fence(
285  "Kokkos::create_mirror_view_and_copy: fence before returning src view"); // same behavior as deep_copy(src, src)
286  return src;
287 }
288 
289 template <class Space, class T, class... P>
290 typename Impl::MirrorViewType<Space, T, P...>::view_type
292  const Space&, const Kokkos::View<T, P...>& src,
293  std::string const& name,
294  typename std::enable_if<
295  std::is_same<typename ViewTraits<T, P...>::specialize,
298 {
299  using src_type = View<T,P...>;
300  using Mirror = typename Impl::MirrorViewType<Space, T, P...>::view_type;
301  std::string label = name.empty() ? src.label() : name;
302  typename src_type::array_layout layout = src.layout();
303  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
304  auto mirror = typename Mirror::non_const_type{
305  view_alloc(WithoutInitializing, label), layout};
306  deep_copy(mirror, src);
307  return mirror;
308 }
309 
310 // Overload of deep_copy for MP::Vector views intializing to a constant scalar
311 template< class DT, class ... DP >
313  const View<DT,DP...> & view ,
314  const typename View<DT,DP...>::array_type::value_type & value
315  , typename std::enable_if<(
316  std::is_same< typename ViewTraits<DT,DP...>::specialize
318  )>::type * )
319 {
320  static_assert(
321  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
322  typename ViewTraits<DT,DP...>::non_const_value_type >::value
323  , "Can only deep copy into non-const type" );
324 
325  typedef typename FlatArrayType< View<DT,DP...> >::type flat_array_type;
327 }
328 
329 // Overload of deep_copy for MP::Vector views intializing to a constant MP::Vector
330 template< class DT, class ... DP >
332  const View<DT,DP...> & view ,
333  const typename View<DT,DP...>::value_type & value
334  , typename std::enable_if<(
335  std::is_same< typename ViewTraits<DT,DP...>::specialize
337  )>::type * )
338 {
339  static_assert(
340  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
341  typename ViewTraits<DT,DP...>::non_const_value_type >::value
342  , "Can only deep copy into non-const type" );
343 
344  // static_assert(
345  // Sacado::StaticSize< typename View<DT,DP...>::value_type >::value
346  // ||
347  // std::is_same< Kokkos::Impl::ActiveExecutionMemorySpace
348  // , Kokkos::HostSpace >::value
349  // , "Deep copy from a FAD type must be statically sized or host space" );
350 
351  Kokkos::Impl::StokhosViewFill< View<DT,DP...> >( view , value );
352 }
353 
354 // Overload of deep_copy for MP::Vector views intializing to a constant scalar
355 template< class ExecSpace , class DT, class ... DP >
357  const ExecSpace &,
358  const View<DT,DP...> & view ,
359  const typename View<DT,DP...>::array_type::value_type & value
360  , typename std::enable_if<(
361  Kokkos::is_execution_space< ExecSpace >::value &&
362  std::is_same< typename ViewTraits<DT,DP...>::specialize
364  )>::type * )
365 {
366  static_assert(
367  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
368  typename ViewTraits<DT,DP...>::non_const_value_type >::value
369  , "Can only deep copy into non-const type" );
370 
371  typedef typename FlatArrayType< View<DT,DP...> >::type flat_array_type;
373 }
374 
375 // Overload of deep_copy for MP::Vector views intializing to a constant MP::Vector
376 template< class ExecSpace , class DT, class ... DP >
378  const ExecSpace &,
379  const View<DT,DP...> & view ,
380  const typename View<DT,DP...>::value_type & value
381  , typename std::enable_if<(
382  Kokkos::is_execution_space< ExecSpace >::value &&
383  std::is_same< typename ViewTraits<DT,DP...>::specialize
385  )>::type * )
386 {
387  static_assert(
388  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
389  typename ViewTraits<DT,DP...>::non_const_value_type >::value
390  , "Can only deep copy into non-const type" );
391 
392  // static_assert(
393  // Sacado::StaticSize< typename View<DT,DP...>::value_type >::value
394  // ||
395  // std::is_same< Kokkos::Impl::ActiveExecutionMemorySpace
396  // , Kokkos::HostSpace >::value
397  // , "Deep copy from a FAD type must be statically sized or host space" );
398 
399  Kokkos::Impl::StokhosViewFill< View<DT,DP...> >( view , value );
400 }
401 
402 /* Specialize for deep copy of MP::Vector */
403 template< class ExecSpace, class DT , class ... DP , class ST , class ... SP >
404 inline
405 void deep_copy( const ExecSpace &,
406  const View<DT,DP...> & dst ,
407  const View<ST,SP...> & src
408  , typename std::enable_if<(
409  std::is_same< typename ViewTraits<DT,DP...>::specialize
411  &&
412  std::is_same< typename ViewTraits<ST,SP...>::specialize
414  )>::type * )
415 {
416  static_assert(
417  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
418  typename ViewTraits<DT,DP...>::non_const_value_type >::value
419  , "Deep copy destination must be non-const" );
420 
421  static_assert(
422  ( unsigned(ViewTraits<DT,DP...>::rank) ==
423  unsigned(ViewTraits<ST,SP...>::rank) )
424  , "Deep copy destination and source must have same rank" );
425 
426  // Note ETP 09/29/2016: Use FlatArrayType instead of array_type to work
427  // around issue where dst and src are rank-1, but have differing layouts.
428  // Kokkos' deep_copy() doesn't work in this case because the array_type
429  // will be rank-2. It should be possible to make deep_copy() work there,
430  // but this seems easier.
431 
432  // Kokkos::deep_copy(
433  // ExecSpace() ,
434  // typename View<DT,DP...>::array_type( dst ) ,
435  // typename View<ST,SP...>::array_type( src ) );
436 
438  ExecSpace() ,
439  typename FlatArrayType< View<DT,DP...> >::type( dst ) ,
440  typename FlatArrayType< View<ST,SP...> >::type( src ) );
441 }
442 
443 /* Specialize for deep copy of MP::Vector */
444 template< class DT , class ... DP , class ST , class ... SP >
445 inline
446 void deep_copy( const View<DT,DP...> & dst ,
447  const View<ST,SP...> & src
448  , typename std::enable_if<(
449  std::is_same< typename ViewTraits<DT,DP...>::specialize
451  &&
452  std::is_same< typename ViewTraits<ST,SP...>::specialize
454  )>::type * )
455 {
456  using exec_space = typename View<DT,DP...>::execution_space;
457  Kokkos::fence();
458  Kokkos::deep_copy(exec_space(), dst, src);
459  Kokkos::fence();
460 }
461 
462 namespace Impl {
463 
464 template <unsigned N, typename... Args>
465 KOKKOS_FUNCTION std::enable_if_t<
466  N == View<Args...>::Rank &&
467  std::is_same<typename ViewTraits<Args...>::specialize,
469  View<Args...>>
470 as_view_of_rank_n(View<Args...> v) {
471  return v;
472 }
473 
474 // Placeholder implementation to compile generic code for DynRankView; should
475 // never be called
476 template <unsigned N, typename T, typename... Args>
477 std::enable_if_t<
478  N != View<T, Args...>::Rank &&
479  std::is_same<typename ViewTraits<T, Args...>::specialize,
481  View<typename RankDataType<typename View<T, Args...>::value_type, N>::type,
482  Args...>>
483 as_view_of_rank_n(View<T, Args...>) {
484  Kokkos::Impl::throw_runtime_exception(
485  "Trying to get at a View of the wrong rank");
486  return {};
487 }
488 
489 }
490 
491 }
492 
493 namespace Kokkos {
494 namespace Impl {
495 
496 template< class DataType , class ArrayLayout , typename StorageType >
497 struct ViewDataAnalysis< DataType /* Original view data type */
498  , ArrayLayout
499  , Sacado::MP::Vector< StorageType > >
500 {
501 private:
502 
504  typedef ViewArrayAnalysis< DataType > array_analysis ;
505  static const int DimVector = StorageType::static_size;
506 
507 public:
508 
509  // Specialized view data mapping:
511 
512  typedef typename array_analysis::dimension dimension ;
514  typedef typename array_analysis::const_value_type const_value_type ;
515  typedef typename array_analysis::non_const_value_type non_const_value_type ;
516 
517  // Generate analogous multidimensional array specification type.
518  typedef typename
519  ViewDataType< value_type , dimension >::type type ;
520  typedef typename
521  ViewDataType< const_value_type , dimension >::type const_type ;
522  typedef typename
523  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
524 
525 private:
526 
527  // A const ?
528  enum { is_const = std::is_same< value_type , const_value_type >::value };
529 
530  // The unwrapped scalar types:
531  typedef typename
532  std::conditional< is_const , const ScalarType , ScalarType >::type
534 
537 
538  // Prepend or append the vector dimension based on ArrayLayout
539  // Note: you can't prepend a static dimension, so use 0 for LayoutLeft
540  typedef typename array_analysis::dimension::
541  template prepend<0>::type
543  typedef typename array_analysis::dimension::
544  template append<DimVector>::type
546  typedef typename std::conditional<
547  std::is_same< ArrayLayout, Kokkos::LayoutLeft>::value,
550 
551 public:
552 
553  // Generate "flattened" multidimensional array specification type.
554  typedef typename
555  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
556 
557  typedef typename
558  ViewDataType< const_scalar_type , scalar_dimension >::type
560 
561  typedef typename
562  ViewDataType< non_const_scalar_type , scalar_dimension >::type
564 };
565 
566 } // namespace Impl
567 } // namespace Kokkos
568 
569 //----------------------------------------------------------------------------
570 
571 namespace Kokkos {
572 namespace Experimental {
573 namespace Impl {
574 
575  template < class ValueType,
576  bool is_static = Sacado::IsStaticallySized<ValueType>::value >
578 
579 // MP::Vector allocation for statically-sized MP::Vector types.
580 // In this case we can reinterpret cast directly between pointers of types
581 // MP::Vector<Storage> and MP::Vector<Storage>::value_type.
582 template <class ValueType>
583 struct MPVectorAllocation<ValueType, true> {
584  typedef ValueType value_type;
585  typedef typename Sacado::ValueType<value_type>::type scalar_type;
586 
589 
590  KOKKOS_INLINE_FUNCTION
591  static constexpr size_t
592  memory_span(const size_t span, const unsigned vector_size) {
593  return span * vector_size * sizeof(scalar_type);
594  }
595 
596  KOKKOS_INLINE_FUNCTION
597  MPVectorAllocation() : value_ptr(0), scalar_ptr(0) {}
598 
599  template <typename T>
600  KOKKOS_INLINE_FUNCTION
602  value_ptr = a.value_ptr;
603  scalar_ptr = a.scalar_ptr;
604  return *this;
605  }
606 
607  KOKKOS_INLINE_FUNCTION
608  void set(value_type* ptr, const size_t span, const unsigned vector_size) {
609  value_ptr = ptr;
610  scalar_ptr = reinterpret_cast<scalar_type*>(ptr);
611  }
612 
613  template <class ExecSpace>
614  struct ConstructDestructFunctor {
615  typedef Kokkos::Impl::ViewValueFunctor< ExecSpace, scalar_type > FunctorType ;
618 
619  ConstructDestructFunctor() = default;
620  ConstructDestructFunctor(const ConstructDestructFunctor&) = default;
621  ConstructDestructFunctor& operator=(const ConstructDestructFunctor&) = default;
622 
623  ConstructDestructFunctor(const ExecSpace & space,
624  const bool initialize,
625  const size_t span,
626  const unsigned vector_size,
627  scalar_type* scalar_ptr) :
628  m_functor( space , scalar_ptr , span*vector_size , "Stokhos_MP_VectorContig_ConstructDestructFunctor1" ),
629  m_initialize(initialize) {}
630 
632  if (m_initialize)
633  m_functor.construct_shared_allocation();
634  }
635 
637  if (m_initialize)
638  m_functor.destroy_shared_allocation();
639  }
640 
641  };
642 
643  template <class ExecSpace>
644  inline ConstructDestructFunctor<ExecSpace>
645  create_functor(const ExecSpace & space,
646  const bool initialize,
647  const size_t span,
648  const unsigned vector_size) const {
649  return ConstructDestructFunctor<ExecSpace>(space, initialize, span, vector_size, scalar_ptr);
650  }
651 
652  // Assign scalar_type pointer to give ptr
653  template <typename T>
654  KOKKOS_INLINE_FUNCTION
655  void assign(T * ptr) {
656  value_ptr = reinterpret_cast<value_type*>(ptr);
657  scalar_ptr = reinterpret_cast<scalar_type*>(ptr);
658  }
659 
660 };
661 
662 // MP::Vector allocation for dynamically-sized MP::Vector types.
663 // In this case we allocate two chunks of data, the first for the the
664 // MP::Vector<Storage> itself and then for the underlying scalar type
665 // (MP::Vector<Storage>::value_type). The memory is laid out with the
666 // former followed by the latter.
667 template <class ValueType>
668 struct MPVectorAllocation<ValueType, false> {
669  typedef ValueType value_type;
670  typedef typename Sacado::ValueType<value_type>::type scalar_type;
671 
674 
675  KOKKOS_INLINE_FUNCTION
676  static constexpr size_t
677  memory_span(const size_t span, const unsigned vector_size) {
678  return span * ( vector_size * sizeof(scalar_type) + sizeof(value_type) );
679  }
680 
681  KOKKOS_INLINE_FUNCTION
682  MPVectorAllocation() : value_ptr(0), scalar_ptr(0) {}
683 
684  template <typename T>
685  KOKKOS_INLINE_FUNCTION
687  value_ptr = a.value_ptr;
688  scalar_ptr = a.scalar_ptr;
689  return *this;
690  }
691 
692  // We are making an assumption the data is laid out as described above,
693  // which in general may not be true if the view is created from memory
694  // allocated elsewhere. We should check for that.
695  KOKKOS_INLINE_FUNCTION
696  void set(value_type* ptr, const size_t span, const unsigned vector_size) {
697  value_ptr = ptr;
698  scalar_ptr = reinterpret_cast<scalar_type*>(ptr+span);
699  }
700 
701  template <class ExecSpace>
702  struct VectorConstruct {
703  ExecSpace m_space;
706  size_t m_span;
707  unsigned m_vector_size;
708 
709  VectorConstruct() = default;
710  VectorConstruct(const VectorConstruct&) = default;
711  VectorConstruct& operator=(const VectorConstruct&) = default;
712 
713  inline
714  VectorConstruct(const ExecSpace& space,
715  value_type* p,
716  scalar_type* sp,
717  const size_t span,
718  const unsigned vector_size) :
719  m_space(space), m_p(p), m_sp(sp), m_span(span), m_vector_size(vector_size) {}
720 
721  inline void execute() {
722  if ( ! m_space.in_parallel() ) {
723  typedef Kokkos::RangePolicy< ExecSpace > PolicyType ;
724  const Kokkos::Impl::ParallelFor< VectorConstruct , PolicyType >
725  closure( *this , PolicyType( 0 , m_span ) );
726  closure.execute();
727  m_space.fence();
728  }
729  else {
730  for ( size_t i = 0 ; i < m_span ; ++i ) operator()(i);
731  }
732  }
733 
734  KOKKOS_INLINE_FUNCTION
735  void operator() (const size_t i) const {
736  new (m_p+i) value_type(m_vector_size, m_sp+i*m_vector_size, false);
737  }
738  };
739 
740  template <class ExecSpace>
741  struct ConstructDestructFunctor {
742  typedef Kokkos::Impl::ViewValueFunctor< ExecSpace, scalar_type > ScalarFunctorType ;
743  typedef VectorConstruct< ExecSpace > VectorFunctorType ;
747 
748  ConstructDestructFunctor() = default;
749  ConstructDestructFunctor(const ConstructDestructFunctor&) = default;
750  ConstructDestructFunctor& operator=(const ConstructDestructFunctor&) = default;
751 
752  ConstructDestructFunctor(const ExecSpace & space,
753  const bool initialize,
754  const size_t span,
755  const unsigned vector_size,
756  scalar_type* scalar_ptr,
757  value_type* value_ptr) :
758  m_scalar_functor( space , scalar_ptr , span*vector_size , "Stokhos_MP_VectorContig_ConstructDestructFunctor2" ),
759  m_vector_functor( space , value_ptr , scalar_ptr , span , vector_size ),
760  m_initialize(initialize) {}
761 
763  // First initialize the scalar_type array
764  if (m_initialize)
765  m_scalar_functor.construct_shared_allocation();
766 
767  // Construct each MP::Vector using memory in scalar_ptr array,
768  // setting pointer to MP::Vector values from values array
769  // Equivalent to:
770  // value_type* p = value_ptr;
771  // scalar_type* sp = scalar_ptr;
772  // for (size_t i=0; i<span; ++i) {
773  // new (p++) value_type(vector_size, sp, false);
774  // sp += vector_size;
775  // }
776  // (we always need to do this, regardless of initialization)
777  m_vector_functor.execute();
778  }
779 
781  // We only need to (possibly) call the destructor on values in the
782  // scalar_type array, since the value_type array is a view into it
783  if (m_initialize)
784  m_scalar_functor.destroy_shared_allocation();
785  }
786 
787  };
788 
789  template <class ExecSpace>
790  inline ConstructDestructFunctor<ExecSpace>
791  create_functor(const ExecSpace & space,
792  const bool initialize,
793  const size_t span,
794  const unsigned vector_size) const {
795  return ConstructDestructFunctor<ExecSpace>(space, initialize, span, vector_size, scalar_ptr, value_ptr);
796  }
797 
798  // Assign scalar_type pointer to give ptr
799  // This makes BIG assumption on how the data was allocated
800  template <typename T>
801  KOKKOS_INLINE_FUNCTION
802  void assign(T * ptr) {
803  value_ptr = reinterpret_cast<value_type*>(ptr);
804  if (ptr != 0)
805  scalar_ptr = value_ptr->coeff();
806  else
807  scalar_ptr = 0;
808  }
809 };
810 
811 }}} // namespace Kokkos::Experimental::Impl
812 
813 namespace Kokkos {
814 namespace Impl {
815 
816 template< class Traits >
817 class ViewMapping< Traits , /* View internal mapping */
818  typename std::enable_if<
819  ( std::is_same< typename Traits::specialize
820  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
821  &&
822  ( std::is_same< typename Traits::array_layout
823  , Kokkos::LayoutLeft >::value
824  ||
825  std::is_same< typename Traits::array_layout
826  , Kokkos::LayoutRight >::value
827  ||
828  std::is_same< typename Traits::array_layout
829  , Kokkos::LayoutStride >::value
830  )
831  )
832  , typename Traits::specialize
833  >::type >
834 {
835 private:
836 
837  template< class , class ... > friend class ViewMapping ;
838  template< class , class ... > friend class Kokkos::View ;
839 
843  typedef typename
844  std::add_const< intrinsic_scalar_type >::type const_intrinsic_scalar_type ;
845 
846  enum { StokhosStorageStaticDimension = stokhos_storage_type::static_size };
847  typedef Sacado::integral_nonzero< unsigned , StokhosStorageStaticDimension > sacado_size_type;
848 
850 
851  typedef ViewOffset< typename Traits::dimension
852  , typename Traits::array_layout
853  , void
855 
856  // Prepend or append the vector dimension based on array_layout
857  // Note: you can't prepend a static dimension, so use 0 for LayoutLeft
858  typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
859  typedef typename array_analysis::dimension array_dimension;
860  typedef ViewOffset< typename array_dimension::
861  template append<StokhosStorageStaticDimension>::type,
862  typename Traits::array_layout,
863  void
865  typedef ViewOffset< typename array_dimension::
866  template prepend<0>::type,
867  typename Traits::array_layout,
868  void
870  typedef typename std::conditional<
871  std::is_same< typename Traits::array_layout, Kokkos::LayoutLeft>::value,
874 
877  unsigned m_stride ;
878  sacado_size_type m_sacado_size ; // Size of sacado dimension
879 
880  // Note: if the view is partitioned, m_sacado_size is not the stride in
881  // memory between consecutive MP::Vector entries for given vector index:
882  //
883  // original_sacado_size = m_stride * m_sacado_size
884  // m_stride = 1 for original allocation.
885  //
886  // Stride here has a slightly different meaning than in the standard
887  // View implementation. For the moment we are assuming no padding within
888  // the view array itself and stride is to allow for partitioning the view
889  // by dividing up the scalar type.
890  //
891  // I suspect we could combine this with the way the stride is managed in
892  // the default view, in which case, I don't think we even need a
893  // specialization
894  //
895  // For reshaping by folding the sacado dimension into its next adjacent
896  // dimension, padding wouldn't generally work. So unless there becomes
897  // a way to turn padding off in the default view, a specialization
898  // will be necessary.
899 
900 public:
901 
902  //----------------------------------------
903  // Domain dimensions
904 
905  enum { Rank = Traits::dimension::rank };
906 
907  // Rank corresponding to the sacado dimension
908  enum { Sacado_Rank = std::is_same< typename Traits::array_layout, Kokkos::LayoutLeft >::value ? 0 : Rank+1 };
909 
910  // Using the internal offset mapping so limit to public rank:
911  template< typename iType >
912  KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
913  { return m_impl_offset.m_dim.extent(r); }
914 
915  KOKKOS_INLINE_FUNCTION constexpr
916  typename Traits::array_layout layout() const
917  { return m_impl_offset.layout(); }
918 
919  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
920  { return m_impl_offset.dimension_0(); }
921  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
922  { return m_impl_offset.dimension_1(); }
923  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
924  { return m_impl_offset.dimension_2(); }
925  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
926  { return m_impl_offset.dimension_3(); }
927  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
928  { return m_impl_offset.dimension_4(); }
929  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
930  { return m_impl_offset.dimension_5(); }
931  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
932  { return m_impl_offset.dimension_6(); }
933  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
934  { return m_impl_offset.dimension_7(); }
935 
936  // Is a regular layout with uniform striding for each index.
937  // Since we all for striding within the data type, we can't guarantee
938  // regular striding
939  using is_regular = std::false_type ;
940 
941  // FIXME: Adjust these for m_stride
942  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const
943  { return m_impl_offset.stride_0(); }
944  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const
945  { return m_impl_offset.stride_1(); }
946  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const
947  { return m_impl_offset.stride_2(); }
948  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const
949  { return m_impl_offset.stride_3(); }
950  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const
951  { return m_impl_offset.stride_4(); }
952  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const
953  { return m_impl_offset.stride_5(); }
954  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const
955  { return m_impl_offset.stride_6(); }
956  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const
957  { return m_impl_offset.stride_7(); }
958 
959  template< typename iType >
960  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const
961  { m_impl_offset.stride(s); }
962 
963  // Size of sacado scalar dimension
964  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
965  { return m_sacado_size.value; }
966 
967  // Whether the storage type is statically sized
968  static const bool is_static = stokhos_storage_type::is_static ;
969 
970  // Whether sacado dimension is contiguous
971  static const bool is_contiguous = true;
972 
973  //----------------------------------------
974  // Range of mapping
975 
976  // Return type of reference operators
978 
981 
983  KOKKOS_INLINE_FUNCTION constexpr size_t span() const
984  { return m_impl_offset.span(); }
985 
987  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
988  { return m_impl_offset.span_is_contiguous() && (m_stride == 1); }
989 
991  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
992  { return m_impl_handle.value_ptr ; }
993 
994  //----------------------------------------
995 
996  KOKKOS_FORCEINLINE_FUNCTION
998  { return *m_impl_handle.value_ptr; }
999 
1000  // FIXME: Check this
1001  template< typename I0 >
1002  KOKKOS_FORCEINLINE_FUNCTION
1003  typename
1004  std::enable_if< std::is_integral<I0>::value &&
1005  ! std::is_same< typename Traits::array_layout , Kokkos::LayoutStride >::value
1006  , reference_type >::type
1007  reference( const I0 & i0 ) const
1008  { return m_impl_handle.value_ptr[m_stride * i0]; }
1009 
1010  // FIXME: Check this
1011  template< typename I0 >
1012  KOKKOS_FORCEINLINE_FUNCTION
1013  typename
1014  std::enable_if< std::is_integral<I0>::value &&
1015  std::is_same< typename Traits::array_layout , Kokkos::LayoutStride >::value
1016  , reference_type >::type
1017  reference( const I0 & i0 ) const
1018  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0) ]; }
1019 
1020  template< typename I0 , typename I1 >
1021  KOKKOS_FORCEINLINE_FUNCTION
1022  reference_type reference( const I0 & i0 , const I1 & i1 ) const
1023  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1) ]; }
1024 
1025  template< typename I0 , typename I1 , typename I2 >
1026  KOKKOS_FORCEINLINE_FUNCTION
1027  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
1028  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1,i2) ]; }
1029 
1030  template< typename I0 , typename I1 , typename I2 , typename I3 >
1031  KOKKOS_FORCEINLINE_FUNCTION
1032  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
1033  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1,i2,i3) ]; }
1034 
1035  template< typename I0 , typename I1 , typename I2 , typename I3
1036  , typename I4 >
1037  KOKKOS_FORCEINLINE_FUNCTION
1038  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1039  , const I4 & i4 ) const
1040  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1,i2,i3,i4) ]; }
1041 
1042  template< typename I0 , typename I1 , typename I2 , typename I3
1043  , typename I4 , typename I5 >
1044  KOKKOS_FORCEINLINE_FUNCTION
1045  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1046  , const I4 & i4 , const I5 & i5 ) const
1047  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1,i2,i3,i4,i5) ]; }
1048 
1049  template< typename I0 , typename I1 , typename I2 , typename I3
1050  , typename I4 , typename I5 , typename I6 >
1051  KOKKOS_FORCEINLINE_FUNCTION
1052  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1053  , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
1054  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1,i2,i3,i4,i5,i6) ]; }
1055 
1056  template< typename I0 , typename I1 , typename I2 , typename I3
1057  , typename I4 , typename I5 , typename I6 , typename I7 >
1058  KOKKOS_FORCEINLINE_FUNCTION
1059  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1060  , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7 ) const
1061  { return m_impl_handle.value_ptr[ m_stride * m_impl_offset(i0,i1,i2,i3,i4,i5,i6,i7) ]; }
1062 
1063  //----------------------------------------
1064 
1066  KOKKOS_INLINE_FUNCTION
1067  static size_t memory_span( typename Traits::array_layout const & layout )
1068  {
1069  // Do not introduce padding...
1070  typedef std::integral_constant< unsigned , 0 > padding ;
1071  offset_type offset( padding(), layout );
1072 
1073  // Always use static dimension if we are static
1074  const unsigned static_dim = StokhosStorageStaticDimension;
1075  if (static_dim > 0)
1076  return handle_type::memory_span( offset.span(), static_dim );
1077 
1078  // Else get size from prescribed layout
1079  const size_t sacado_size =
1081  return handle_type::memory_span( offset.span(), sacado_size );
1082  }
1083 
1084  //----------------------------------------
1085 
1086  KOKKOS_DEFAULTED_FUNCTION ~ViewMapping() = default ;
1087  KOKKOS_INLINE_FUNCTION ViewMapping() :
1088  m_impl_handle(),
1089  m_impl_offset(),
1090  m_stride(1),
1091  m_sacado_size(0)
1092  {}
1093 
1094  KOKKOS_DEFAULTED_FUNCTION ViewMapping( const ViewMapping & ) = default ;
1095  KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
1096 
1097  KOKKOS_DEFAULTED_FUNCTION ViewMapping( ViewMapping && ) = default ;
1098  KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
1099 
1100  template< class ... P >
1101  KOKKOS_INLINE_FUNCTION
1102  ViewMapping
1103  ( ViewCtorProp< P ... > const & prop
1104  , typename Traits::array_layout const & layout
1105  )
1106  : m_impl_handle()
1107  , m_impl_offset( std::integral_constant< unsigned , 0 >()
1108  , layout )
1109  , m_stride( 1 )
1110  , m_sacado_size( Kokkos::Impl::GetSacadoSize<unsigned(Rank)>::eval(layout) )
1111  {
1112  m_impl_handle.set( ( (ViewCtorProp<void,pointer_type> const &) prop ).value,
1113  m_impl_offset.span(), m_sacado_size.value );
1114  }
1115 
1117  KOKKOS_INLINE_FUNCTION
1118  void assign_data( pointer_type arg_ptr )
1119  { m_impl_handle.set( arg_ptr, m_impl_offset.span(), m_sacado_size.value ); }
1120 
1121  //----------------------------------------
1122  /* Allocate and construct mapped array.
1123  * Allocate via shared allocation record and
1124  * return that record for allocation tracking.
1125  */
1126  template< class ... P >
1127  SharedAllocationRecord<> *
1128  allocate_shared( ViewCtorProp< P... > const & prop
1129  , typename Traits::array_layout const & layout )
1130  {
1131  typedef ViewCtorProp< P... > ctor_prop ;
1132 
1133  typedef typename ctor_prop::execution_space execution_space ;
1134  typedef typename Traits::memory_space memory_space ;
1135  typedef typename handle_type::template ConstructDestructFunctor<execution_space> functor_type ;
1136  typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
1137 
1138  // Disallow padding
1139  typedef std::integral_constant< unsigned , 0 > padding ;
1140 
1141  m_impl_offset = offset_type( padding(), layout );
1142  m_stride = 1;
1143  m_sacado_size = Kokkos::Impl::GetSacadoSize<unsigned(Rank)>::eval(layout);
1144 
1145  const size_t alloc_size =
1146  handle_type::memory_span( m_impl_offset.span(), m_sacado_size.value );
1147 
1148  // Create shared memory tracking record with allocate memory from the memory space
1149  record_type * const record =
1150  record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
1151  , ( (ViewCtorProp<void,std::string> const &) prop ).value
1152  , alloc_size );
1153 
1154  // Only set the the pointer and initialize if the allocation is non-zero.
1155  // May be zero if one of the dimensions is zero.
1156  if ( alloc_size ) {
1157 
1158  m_impl_handle.set( reinterpret_cast< pointer_type >( record->data() ),
1159  m_impl_offset.span(), m_sacado_size.value );
1160 
1161  // Assume destruction is only required when construction is requested.
1162  // The ViewValueFunctor has both value construction and destruction operators.
1163  record->m_destroy = m_impl_handle.create_functor(
1164  ( (ViewCtorProp<void,execution_space> const &) prop).value
1165  , ctor_prop::initialize
1166  , m_impl_offset.span()
1167  , m_sacado_size.value );
1168 
1169  // Construct values
1170  record->m_destroy.construct_shared_allocation();
1171  }
1172 
1173  return record ;
1174  }
1175 
1176  template< class ... P >
1177  SharedAllocationRecord<> *
1178  allocate_shared( ViewCtorProp< P... > const & prop
1179  , typename Traits::array_layout const & layout
1180  , bool /*execution_space_specified*/)
1181  {
1182  return allocate_shared(prop, layout);
1183  }
1184 
1185  //----------------------------------------
1186  // If the View is to construct or destroy the elements.
1187 
1188  /*
1189  template< class ExecSpace >
1190  void construct( const ExecSpace & space ) const
1191  {
1192  m_impl_handle.construct( space, m_impl_offset.span(), m_sacado_size.value );
1193  }
1194 
1195  template< class ExecSpace >
1196  void destroy( const ExecSpace & space ) const
1197  {
1198  m_impl_handle.destruct( space, m_impl_offset.span(), m_sacado_size.value );
1199  }
1200  */
1201 };
1202 
1203 } // namespace Impl
1204 } // namespace Kokkos
1205 
1206 //----------------------------------------------------------------------------
1207 
1208 namespace Kokkos {
1209 namespace Impl {
1210 
1215 template< class DstTraits , class SrcTraits >
1216 class ViewMapping< DstTraits , SrcTraits ,
1217  typename std::enable_if<(
1218  Kokkos::Impl::MemorySpaceAccess< typename DstTraits::memory_space
1219  , typename SrcTraits::memory_space >::assignable
1220  &&
1221  // Destination view has MP::Vector
1222  std::is_same< typename DstTraits::specialize
1223  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
1224  &&
1225  // Source view has MP::Vector only
1226  std::is_same< typename SrcTraits::specialize
1227  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
1228  )
1229  , typename DstTraits::specialize
1230  >::type >
1231 {
1232 public:
1233 
1234  enum { is_assignable = true };
1235  enum { is_assignable_data_type = true };
1236 
1237  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1238  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1239  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcType ;
1240 
1241  KOKKOS_INLINE_FUNCTION static
1242  void assign( DstType & dst
1243  , const SrcType & src
1244  , const TrackType & )
1245  {
1246  static_assert(
1247  (
1248  std::is_same< typename DstTraits::array_layout
1249  , Kokkos::LayoutLeft >::value ||
1250  std::is_same< typename DstTraits::array_layout
1251  , Kokkos::LayoutRight >::value ||
1252  std::is_same< typename DstTraits::array_layout
1253  , Kokkos::LayoutStride >::value
1254  )
1255  &&
1256  (
1257  std::is_same< typename SrcTraits::array_layout
1258  , Kokkos::LayoutLeft >::value ||
1259  std::is_same< typename SrcTraits::array_layout
1260  , Kokkos::LayoutRight >::value ||
1261  std::is_same< typename SrcTraits::array_layout
1262  , Kokkos::LayoutStride >::value
1263  )
1264  , "View of MP::Vector requires LayoutLeft, LayoutRight, or LayoutStride" );
1265 
1266  static_assert(
1267  std::is_same< typename DstTraits::array_layout
1268  , typename SrcTraits::array_layout >::value ||
1269  std::is_same< typename DstTraits::array_layout
1270  , Kokkos::LayoutStride >::value ||
1271  ( unsigned(DstTraits::rank) == 0 && unsigned(SrcTraits::rank) == 0 ) ||
1272  ( unsigned(DstTraits::rank) == 1 && unsigned(SrcTraits::rank) == 1 ) ,
1273  "View assignment must have compatible layout" );
1274 
1275  static_assert(
1276  std::is_same< typename DstTraits::value_type
1277  , typename SrcTraits::value_type >::value ||
1278  std::is_same< typename DstTraits::value_type
1279  , typename SrcTraits::const_value_type >::value ,
1280  "View assignment must have same value type or const = non-const" );
1281 
1282  static_assert(
1283  ViewDimensionAssignable
1284  < typename DstType::offset_type::dimension_type
1285  , typename SrcType::offset_type::dimension_type >::value ,
1286  "View assignment must have compatible dimensions" );
1287 
1288  dst.m_impl_handle = src.m_impl_handle ;
1289  dst.m_impl_offset = src.m_impl_offset ;
1290  dst.m_stride = src.m_stride ;
1291  dst.m_sacado_size = src.m_sacado_size ;
1292  }
1293 };
1294 
1300 template< class DstTraits , class SrcTraits >
1301 class ViewMapping< DstTraits , SrcTraits ,
1302  typename std::enable_if<(
1303  Kokkos::Impl::MemorySpaceAccess< typename DstTraits::memory_space
1304  , typename SrcTraits::memory_space >::assignable
1305  &&
1306  // Destination view has ordinary
1307  std::is_same< typename DstTraits::specialize , void >::value
1308  &&
1309  // Source view has MP::Vector only
1310  std::is_same< typename SrcTraits::specialize
1311  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
1312  &&
1313  // Ranks match
1314  unsigned(DstTraits::dimension::rank) == unsigned(SrcTraits::dimension::rank)+1
1315  )
1316  , typename DstTraits::specialize
1317  >::type >
1318 {
1319 public:
1320 
1321  enum { is_assignable = true };
1322  enum { is_assignable_data_type = true };
1323 
1324  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1325  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1326  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcType ;
1327 
1328  KOKKOS_INLINE_FUNCTION static
1329  void assign( DstType & dst
1330  , const SrcType & src
1331  , const TrackType & )
1332  {
1333  static_assert(
1334  (
1335  std::is_same< typename DstTraits::array_layout
1336  , Kokkos::LayoutLeft >::value ||
1337  std::is_same< typename DstTraits::array_layout
1338  , Kokkos::LayoutRight >::value ||
1339  std::is_same< typename DstTraits::array_layout
1340  , Kokkos::LayoutStride >::value
1341  )
1342  &&
1343  (
1344  std::is_same< typename SrcTraits::array_layout
1345  , Kokkos::LayoutLeft >::value ||
1346  std::is_same< typename SrcTraits::array_layout
1347  , Kokkos::LayoutRight >::value ||
1348  std::is_same< typename SrcTraits::array_layout
1349  , Kokkos::LayoutStride >::value
1350  )
1351  , "View of MP::Vector requires LayoutLeft, LayoutRight, or LayoutStride" );
1352 
1353  static_assert(
1354  std::is_same< typename DstTraits::array_layout
1355  , typename SrcTraits::array_layout >::value ||
1356  std::is_same< typename DstTraits::array_layout
1357  , Kokkos::LayoutStride >::value ,
1358  "View assignment must have compatible layout" );
1359 
1360  static_assert(
1361  std::is_same< typename DstTraits::scalar_array_type
1362  , typename SrcTraits::scalar_array_type >::value ||
1363  std::is_same< typename DstTraits::scalar_array_type
1364  , typename SrcTraits::const_scalar_array_type >::value ,
1365  "View assignment must have same value type or const = non-const" );
1366 
1367  static_assert(
1368  ViewDimensionAssignable<
1369  typename DstType::offset_type::dimension_type,
1370  typename SrcType::array_offset_type::dimension_type >::value,
1371  "View assignment must have compatible dimensions" );
1372 
1373  if ( src.m_stride != 1 ) {
1374  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::MP::Vector ... > cannot assign with non-unit stride ******\n\n");
1375  }
1376 
1377  unsigned dims[8];
1378  dims[0] = src.m_impl_offset.dimension_0();
1379  dims[1] = src.m_impl_offset.dimension_1();
1380  dims[2] = src.m_impl_offset.dimension_2();
1381  dims[3] = src.m_impl_offset.dimension_3();
1382  dims[4] = src.m_impl_offset.dimension_4();
1383  dims[5] = src.m_impl_offset.dimension_5();
1384  dims[6] = src.m_impl_offset.dimension_6();
1385  dims[7] = src.m_impl_offset.dimension_7();
1386  unsigned rank = SrcTraits::dimension::rank;
1387  unsigned sacado_size = src.m_sacado_size.value;
1388  if (std::is_same<typename SrcTraits::array_layout, LayoutLeft>::value) {
1389  // Move sacado_size to the first dimension, shift all others up one
1390  for (unsigned i=rank; i>0; --i)
1391  dims[i] = dims[i-1];
1392  dims[0] = sacado_size;
1393  }
1394  else {
1395  dims[rank] = sacado_size;
1396  }
1397  typedef typename DstType::offset_type dst_offset_type;
1398  dst.m_impl_offset = dst_offset_type( std::integral_constant< unsigned , 0 >(),
1399  typename DstTraits::array_layout(
1400  dims[0] , dims[1] , dims[2] , dims[3] ,
1401  dims[4] , dims[5] , dims[6] , dims[7] ) );
1402  dst.m_impl_handle = src.m_impl_handle.scalar_ptr ;
1403  }
1404 };
1405 
1412 template< class DstTraits , class SrcTraits >
1413 class ViewMapping< DstTraits , SrcTraits ,
1414  typename std::enable_if<(
1415  Kokkos::Impl::MemorySpaceAccess< typename DstTraits::memory_space
1416  , typename SrcTraits::memory_space >::assignable
1417  &&
1418  // Destination view has ordinary
1419  std::is_same< typename DstTraits::specialize , void >::value
1420  &&
1421  // Source view has MP::Vector only
1422  std::is_same< typename SrcTraits::specialize
1423  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
1424  &&
1425  // Ranks match
1426  unsigned(DstTraits::dimension::rank) == unsigned(SrcTraits::dimension::rank)
1427  )
1428  , typename DstTraits::specialize
1429  >::type >
1430 {
1431 public:
1432 
1433  enum { is_assignable = true };
1434  enum { is_assignable_data_type = true };
1435 
1436  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1437  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1438  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcType ;
1439 
1440  KOKKOS_INLINE_FUNCTION static
1441  void assign( DstType & dst
1442  , const SrcType & src
1443  , const TrackType & )
1444  {
1445  static_assert(
1446  (
1447  std::is_same< typename DstTraits::array_layout
1448  , Kokkos::LayoutLeft >::value ||
1449  std::is_same< typename DstTraits::array_layout
1450  , Kokkos::LayoutRight >::value ||
1451  std::is_same< typename DstTraits::array_layout
1452  , Kokkos::LayoutStride >::value
1453  )
1454  &&
1455  (
1456  std::is_same< typename SrcTraits::array_layout
1457  , Kokkos::LayoutLeft >::value ||
1458  std::is_same< typename SrcTraits::array_layout
1459  , Kokkos::LayoutRight >::value ||
1460  std::is_same< typename SrcTraits::array_layout
1461  , Kokkos::LayoutStride >::value
1462  )
1463  , "View of MP::Vector requires LayoutLeft, LayoutRight, or LayoutStride" );
1464 
1465  static_assert(
1466  std::is_same< typename DstTraits::array_layout
1467  , typename SrcTraits::array_layout >::value ||
1468  std::is_same< typename DstTraits::array_layout
1469  , Kokkos::LayoutStride >::value ,
1470  "View assignment must have compatible layout" );
1471 
1472  static_assert(
1473  std::is_same< typename DstTraits::value_type
1474  , typename SrcTraits::non_const_value_type::value_type >::value ||
1475  std::is_same< typename DstTraits::value_type
1476  , const typename SrcTraits::non_const_value_type::value_type >::value ,
1477  "View assignment must have same value type or const = non-const" );
1478 
1479  static_assert(
1480  ViewDimensionAssignable<
1481  typename DstType::offset_type::dimension_type,
1482  typename SrcType::offset_type::dimension_type >::value,
1483  "View assignment must have compatible dimensions" );
1484 
1485  if ( src.m_stride != 1 ) {
1486  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::MP::Vector ... > cannot assign with non-unit stride ******\n\n");
1487  }
1488 
1489  unsigned dims[8];
1490  dims[0] = src.m_impl_offset.dimension_0();
1491  dims[1] = src.m_impl_offset.dimension_1();
1492  dims[2] = src.m_impl_offset.dimension_2();
1493  dims[3] = src.m_impl_offset.dimension_3();
1494  dims[4] = src.m_impl_offset.dimension_4();
1495  dims[5] = src.m_impl_offset.dimension_5();
1496  dims[6] = src.m_impl_offset.dimension_6();
1497  dims[7] = src.m_impl_offset.dimension_7();
1498  unsigned rank = SrcTraits::dimension::rank;
1499  unsigned sacado_size = src.m_sacado_size.value;
1500  if (std::is_same<typename DstTraits::array_layout, LayoutLeft>::value) {
1501  dims[0] = dims[0]*sacado_size;
1502  dims[rank] = 0;
1503  }
1504  else {
1505  dims[rank-1] = dims[rank-1]*sacado_size;
1506  dims[rank] = 0;
1507  }
1508  typedef typename DstType::offset_type dst_offset_type;
1509  dst.m_impl_offset = dst_offset_type( std::integral_constant< unsigned , 0 >(),
1510  typename DstTraits::array_layout(
1511  dims[0] , dims[1] , dims[2] , dims[3] ,
1512  dims[4] , dims[5] , dims[6] , dims[7] ) );
1513  dst.m_impl_handle = src.m_impl_handle.scalar_ptr ;
1514  }
1515 };
1516 
1517 } // namespace Impl
1518 } // namespace Kokkos
1519 
1520 //----------------------------------------------------------------------------
1521 
1522 namespace Kokkos {
1523 namespace Impl {
1524 
1525 // Subview mapping
1526 
1527 template< class DataType, class ... P , class Arg0, class ... Args >
1528 struct ViewMapping
1529  < typename std::enable_if<(
1530  // Source view has MP::Vector only
1531  std::is_same< typename Kokkos::ViewTraits<DataType,P...>::specialize
1532  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
1533  &&
1534  (
1535  std::is_same< typename Kokkos::ViewTraits<DataType,P...>::array_layout
1536  , Kokkos::LayoutLeft >::value ||
1537  std::is_same< typename Kokkos::ViewTraits<DataType,P...>::array_layout
1538  , Kokkos::LayoutRight >::value ||
1539  std::is_same< typename Kokkos::ViewTraits<DataType,P...>::array_layout
1540  , Kokkos::LayoutStride >::value
1541  )
1542  && !Sacado::MP::is_vector_partition<Arg0>::value
1543  )>::type
1544  , Kokkos::ViewTraits<DataType,P...>
1545  , Arg0, Args ... >
1546 {
1547 private:
1548 
1549  typedef Kokkos::ViewTraits<DataType,P...> SrcTraits;
1550 
1551  //static_assert( SrcTraits::rank == sizeof...(Args) , "" );
1552 
1553  enum
1554  { RZ = false
1555  , R0 = bool(is_integral_extent<0,Arg0,Args...>::value)
1556  , R1 = bool(is_integral_extent<1,Arg0,Args...>::value)
1557  , R2 = bool(is_integral_extent<2,Arg0,Args...>::value)
1558  , R3 = bool(is_integral_extent<3,Arg0,Args...>::value)
1559  , R4 = bool(is_integral_extent<4,Arg0,Args...>::value)
1560  , R5 = bool(is_integral_extent<5,Arg0,Args...>::value)
1561  , R6 = bool(is_integral_extent<6,Arg0,Args...>::value)
1562  };
1563 
1564  // Public rank
1565  enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
1566  + unsigned(R4) + unsigned(R5) + unsigned(R6) };
1567 
1568  // Whether right-most non-MP::Vector rank is a range.
1569  enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
1570  1 == SrcTraits::rank ? R0 : (
1571  2 == SrcTraits::rank ? R1 : (
1572  3 == SrcTraits::rank ? R2 : (
1573  4 == SrcTraits::rank ? R3 : (
1574  5 == SrcTraits::rank ? R4 : (
1575  6 == SrcTraits::rank ? R5 : R6 ))))))) };
1576 
1577  // Subview's layout
1578  typedef typename std::conditional<
1579  ( /* Same array layout IF */
1580  ( rank == 0 ) /* output rank zero */
1581  ||
1582  // OutputRank 1 or 2, InputLayout Left, Interval 0
1583  // because single stride one or second index has a stride.
1584  ( rank <= 2 && R0 && std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutLeft >::value )
1585  ||
1586  // OutputRank 1 or 2, InputLayout Right, Interval [InputRank-1]
1587  // because single stride one or second index has a stride.
1588  ( rank <= 2 && R0_rev && std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutRight >::value )
1589  ), typename SrcTraits::array_layout , Kokkos::LayoutStride
1591 
1593 
1594  typedef typename std::conditional< rank == 0 , sacado_mp_vector_type ,
1595  typename std::conditional< rank == 1 , sacado_mp_vector_type * ,
1596  typename std::conditional< rank == 2 , sacado_mp_vector_type ** ,
1597  typename std::conditional< rank == 3 , sacado_mp_vector_type *** ,
1598  typename std::conditional< rank == 4 , sacado_mp_vector_type **** ,
1599  typename std::conditional< rank == 5 , sacado_mp_vector_type ***** ,
1600  typename std::conditional< rank == 6 , sacado_mp_vector_type ****** ,
1601  sacado_mp_vector_type *******
1604 
1605 public:
1606 
1607  typedef Kokkos::ViewTraits
1608  < data_type
1609  , array_layout
1610  , typename SrcTraits::device_type
1611  , typename SrcTraits::memory_traits > traits_type ;
1612 
1613  typedef Kokkos::View
1614  < data_type
1615  , array_layout
1616  , typename SrcTraits::device_type
1617  , typename SrcTraits::memory_traits > type ;
1618 
1619 
1620  // The presumed type is 'ViewMapping< traits_type , void >'
1621  // However, a compatible ViewMapping is acceptable.
1622  template< class DstTraits >
1623  KOKKOS_INLINE_FUNCTION
1624  static void assign( ViewMapping< DstTraits , typename DstTraits::specialize > & dst
1625  , ViewMapping< SrcTraits , typename SrcTraits::specialize > const & src
1626  , Arg0 arg0, Args ... args )
1627  {
1628  static_assert(
1629  ViewMapping< DstTraits , traits_type , typename DstTraits::specialize >::is_assignable ,
1630  "Subview destination type must be compatible with subview derived type" );
1631 
1632  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1633  typedef typename DstType::offset_type dst_offset_type ;
1634 
1635  const SubviewExtents< SrcTraits::rank , rank >
1636  extents( src.m_impl_offset.m_dim , arg0 , args... );
1637 
1638  const size_t offset = src.m_impl_offset( extents.domain_offset(0)
1639  , extents.domain_offset(1)
1640  , extents.domain_offset(2)
1641  , extents.domain_offset(3)
1642  , extents.domain_offset(4)
1643  , extents.domain_offset(5)
1644  , extents.domain_offset(6)
1645  , extents.domain_offset(7) );
1646 
1647  dst.m_impl_offset = dst_offset_type( src.m_impl_offset , extents );
1648  dst.m_impl_handle.value_ptr = src.m_impl_handle.value_ptr + offset;
1649  dst.m_impl_handle.scalar_ptr =
1650  src.m_impl_handle.scalar_ptr + offset * src.m_stride * src.m_sacado_size.value;
1651  dst.m_stride = src.m_stride;
1652  dst.m_sacado_size = src.m_sacado_size;
1653  }
1654 
1655 };
1656 
1657 } // namespace Impl
1658 } // namespace Kokkos
1659 
1660 //----------------------------------------------------------------------------
1661 //----------------------------------------------------------------------------
1662 //----------------------------------------------------------------------------
1663 
1664 namespace Kokkos {
1665 namespace Impl {
1666 
1667 // Partition mapping
1668 
1669 template< class DataType, class ...P, unsigned Size >
1670 class ViewMapping<
1671  void,
1672  ViewTraits<DataType,P...> ,
1673  Sacado::MP::VectorPartition<Size> >
1674 {
1675 public:
1676 
1677  enum { is_assignable = true };
1678  enum { is_assignable_data_type = true };
1679 
1680  typedef ViewTraits<DataType,P...> src_traits;
1681  typedef ViewMapping< src_traits , typename src_traits::specialize > src_type ;
1682 
1683  typedef typename src_type::offset_type::dimension_type src_dimension;
1686  typedef typename storage_type::template apply_N<Size> storage_apply;
1687  typedef typename storage_apply::type strided_storage_type;
1689  typedef typename
1690  ViewDataType< strided_value_type , src_dimension >::type strided_data_type;
1691  typedef ViewTraits<strided_data_type,P...> dst_traits;
1692  typedef View<strided_data_type,P...> type;
1693  typedef ViewMapping< dst_traits , typename dst_traits::specialize > dst_type ;
1694 
1695  KOKKOS_INLINE_FUNCTION static
1696  void assign( dst_type & dst
1697  , const src_type & src
1698  , const Sacado::MP::VectorPartition<Size> & part )
1699  {
1700  // The pointer assignments below are not sufficient for dynamically sized
1701  // scalar types, so disallow this case for now
1702  static_assert( storage_type::is_static,
1703  "For performance reasons, partitioned assignment is only implemented for statically-sized MP::Vector types" );
1704 
1705  unsigned len = part.end - part.begin;
1706  if ( Size != len || Size == 0 ) {
1707  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::MP::Vector ... > Invalid size in partitioned view assignment ******\n\n");
1708  }
1709 
1710  dst.m_impl_handle.value_ptr =
1711  reinterpret_cast<strided_value_type*>( src.m_impl_handle.value_ptr ) +
1712  part.begin / len ;
1713  dst.m_impl_handle.scalar_ptr = src.m_impl_handle.scalar_ptr +
1714  (part.begin / len) * src.m_stride * src.m_sacado_size.value ;
1715  dst.m_impl_offset = src.m_impl_offset ;
1716  dst.m_stride = src.m_stride * src.m_sacado_size.value / Size ;
1717  dst.m_sacado_size = len ;
1718  }
1719 };
1720 
1721 } // namespace Impl
1722 } // namespace Kokkos
1723 
1724 namespace Kokkos {
1725 
1726 template< unsigned Size, typename D, typename ... P >
1727 KOKKOS_INLINE_FUNCTION
1728 typename Kokkos::Impl::ViewMapping< void, typename Kokkos::ViewTraits<D,P...>, Sacado::MP::VectorPartition<Size> >::type
1729 partition( const Kokkos::View<D,P...> & src ,
1730  const unsigned beg )
1731 {
1732  typedef Kokkos::ViewTraits<D,P...> traits;
1733  typedef typename Kokkos::Impl::ViewMapping< void, traits, Sacado::MP::VectorPartition<Size> >::type DstViewType;
1734  const Sacado::MP::VectorPartition<Size> part( beg , beg+Size );
1735  return DstViewType(src, part);
1736 }
1737 
1738 } // namespace Kokkos
1739 
1740 //----------------------------------------------------------------------------
1741 //----------------------------------------------------------------------------
1742 //----------------------------------------------------------------------------
1743 
1744 namespace Kokkos {
1745 namespace Impl {
1746 
1747 // Specialization for deep_copy( view, view::value_type ) for Cuda
1748 #if defined( KOKKOS_ENABLE_CUDA )
1749 template< class OutputView >
1750 struct StokhosViewFill< OutputView ,
1751  typename std::enable_if< std::is_same< typename OutputView::specialize,
1752  Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value &&
1753  std::is_same< typename OutputView::execution_space,
1754  Cuda >::value >::type >
1755 {
1756  typedef typename OutputView::const_value_type const_value_type ;
1757  typedef typename OutputView::execution_space execution_space ;
1758  typedef typename OutputView::size_type size_type ;
1759 
1760  template <unsigned VectorLength>
1761  struct Kernel {
1762  typedef typename OutputView::execution_space execution_space ;
1763  const OutputView output;
1765 
1766  Kernel( const OutputView & arg_out , const_value_type & arg_in ) :
1767  output(arg_out), input(arg_in) {}
1768 
1769  typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ;
1770 
1771  KOKKOS_INLINE_FUNCTION
1772  void operator()( const team_member & dev ) const
1773  {
1774  const size_type tidx = dev.team_rank() % VectorLength;
1775  const size_type tidy = dev.team_rank() / VectorLength;
1776  const size_type nrow = dev.team_size() / VectorLength;
1777  const size_type nvec = dimension_scalar(output);
1778 
1779  const size_type i0 = dev.league_rank() * nrow + tidy;
1780  if ( i0 >= output.extent(0) ) return;
1781 
1782  for ( size_type i1 = 0 ; i1 < output.extent(1) ; ++i1 ) {
1783  for ( size_type i2 = 0 ; i2 < output.extent(2) ; ++i2 ) {
1784  for ( size_type i3 = 0 ; i3 < output.extent(3) ; ++i3 ) {
1785  for ( size_type i4 = 0 ; i4 < output.extent(4) ; ++i4 ) {
1786  for ( size_type i5 = 0 ; i5 < output.extent(5) ; ++i5 ) {
1787  for ( size_type i6 = 0 ; i6 < output.extent(6) ; ++i6 ) {
1788  for ( size_type i7 = 0 ; i7 < output.extent(7) ; ++i7 ) {
1789  for ( size_type is = tidx ; is < nvec ; is+=VectorLength ) {
1790  output.access(i0,i1,i2,i3,i4,i5,i6,i7).fastAccessCoeff(is) =
1791  input.fastAccessCoeff(is) ;
1792  }}}}}}}}
1793  }
1794  };
1795 
1796  StokhosViewFill( const OutputView & output , const_value_type & input )
1797  {
1798  if ( Sacado::is_constant(input) ) {
1799  deep_copy( output , input.fastAccessCoeff(0) );
1800  }
1801  else {
1802 
1803  // Coalesced accesses are 128 bytes in size
1805  const unsigned vector_length =
1806  ( 128 + sizeof(scalar_type)-1 ) / sizeof(scalar_type);
1807 
1808  // 8 warps per block should give good occupancy
1809  const size_type block_size = 256;
1810 
1811  const size_type rows_per_block = block_size / vector_length;
1812  const size_type n = output.extent(0);
1813  const size_type league_size = ( n + rows_per_block-1 ) / rows_per_block;
1814  const size_type team_size = rows_per_block * vector_length;
1815  Kokkos::TeamPolicy< execution_space > config( league_size, team_size );
1816 
1817  parallel_for( config, Kernel<vector_length>(output, input) );
1818  execution_space().fence();
1819  }
1820  }
1821 
1822 };
1823 #endif /* #if defined( KOKKOS_ENABLE_CUDA ) */
1824 
1825 } // namespace Impl
1826 } // namespace Kokkos
1827 
1828 //----------------------------------------------------------------------------
1829 //----------------------------------------------------------------------------
1830 //----------------------------------------------------------------------------
1831 
1832 namespace Kokkos {
1833 namespace Impl {
1834 
1835 struct ViewSpecializeSacadoFad;
1836 
1843 template< class DstTraits , class SrcTraits >
1844 class ViewMapping< DstTraits , SrcTraits ,
1845  typename std::enable_if<(
1846  Kokkos::Impl::MemorySpaceAccess< typename DstTraits::memory_space
1847  , typename SrcTraits::memory_space >::assignable
1848  &&
1849  // Destination view has MP::Vector only
1850  std::is_same< typename DstTraits::specialize
1851  , Kokkos::Experimental::Impl::ViewMPVectorContiguous >::value
1852  &&
1853  // Source view has FAD only
1854  std::is_same< typename SrcTraits::specialize
1855  , ViewSpecializeSacadoFad >::value
1856  )
1857  , typename DstTraits::specialize
1858  >::type >
1859 {
1860 public:
1861 
1862  enum { is_assignable = true };
1863  enum { is_assignable_data_type = true };
1864 
1865  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1866  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1867  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1868 
1869  template< class DstType >
1870  KOKKOS_INLINE_FUNCTION static
1871  void assign( DstType & dst
1872  , const SrcFadType & src
1873  , const TrackType & )
1874  {
1875  static_assert(
1876  (
1877  std::is_same< typename DstTraits::array_layout
1878  , Kokkos::LayoutLeft >::value ||
1879  std::is_same< typename DstTraits::array_layout
1880  , Kokkos::LayoutRight >::value ||
1881  std::is_same< typename DstTraits::array_layout
1882  , Kokkos::LayoutStride >::value
1883  )
1884  &&
1885  (
1886  std::is_same< typename SrcTraits::array_layout
1887  , Kokkos::LayoutLeft >::value ||
1888  std::is_same< typename SrcTraits::array_layout
1889  , Kokkos::LayoutRight >::value ||
1890  std::is_same< typename SrcTraits::array_layout
1891  , Kokkos::LayoutStride >::value
1892  )
1893  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1894 
1895  static_assert(
1896  std::is_same< typename DstTraits::array_layout
1897  , typename SrcTraits::array_layout >::value ||
1898  std::is_same< typename DstTraits::array_layout
1899  , Kokkos::LayoutStride >::value ,
1900  "View assignment must have compatible layout" );
1901 
1902  static_assert(
1903  std::is_same< typename DstTraits::data_type
1904  , typename SrcTraits::scalar_array_type >::value ||
1905  std::is_same< typename DstTraits::data_type
1906  , typename SrcTraits::const_scalar_array_type >::value ,
1907  "View assignment must have same value type or const = non-const" );
1908 
1909  static_assert(
1910  ViewDimensionAssignable
1911  < typename DstType::offset_type::dimension_type
1912  , typename SrcFadType::array_offset_type::dimension_type >::value ,
1913  "View assignment must have compatible dimensions" );
1914 
1915  typedef typename DstType::offset_type dst_offset_type ;
1916 
1917  dst.m_impl_offset = dst_offset_type( src.m_array_offset );
1918  dst.m_impl_handle.assign(src.m_impl_handle) ;
1919  dst.m_stride = 1;
1920 
1921  // Don't need to set dst.m_sacado_size since it is determined statically
1922  static_assert( DstType::is_static,
1923  "Destination view must be statically allocated" );
1924  }
1925 };
1926 
1927 } // namespace Impl
1928 } // namespace Kokkos
1929 
1930 //----------------------------------------------------------------------------
1931 //----------------------------------------------------------------------------
1932 //----------------------------------------------------------------------------
1933 
1934 #include "Kokkos_View_Utils_Def.hpp"
1935 
1936 #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_MP_VECTOR_CONTIGUOUS_HPP */
KOKKOS_FUNCTION std::enable_if_t< N==View< Args... >::Rank &&std::is_same< typename ViewTraits< Args... >::specialize, Kokkos::Experimental::Impl::ViewPCEContiguous >::value, View< Args... > > as_view_of_rank_n(View< Args... > v)
static KOKKOS_INLINE_FUNCTION void assign(dst_type &dst, const src_type &src, const Sacado::MP::VectorPartition< Size > &part)
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
std::conditional< std::is_same< ArrayLayout, Kokkos::LayoutLeft >::value, prepend_scalar_dimension, append_scalar_dimension >::type scalar_dimension
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
OutputView::const_value_type const_value_type
VectorConstruct(const ExecSpace &space, value_type *p, scalar_type *sp, const size_t span, const unsigned vector_size)
static KOKKOS_INLINE_FUNCTION constexpr size_t memory_span(const size_t span, const unsigned vector_size)
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< View< T, P... > >::value, unsigned >::type dimension_scalar(const View< T, P... > &view)
OutputView::execution_space execution_space
KOKKOS_INLINE_FUNCTION void operator()(const size_t i0) const
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)
StokhosViewFill(const OutputView &arg_out, const_value_type &arg_in)
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)
KOKKOS_INLINE_FUNCTION Kokkos::Impl::ViewMapping< void, typename Kokkos::ViewTraits< D, P... >, Sacado::MP::VectorPartition< Size > >::type partition(const Kokkos::View< D, P... > &src, const unsigned beg)
Impl::MirrorViewType< Space, T, P... >::view_type create_mirror_view_and_copy(const Space &, const Kokkos::View< T, P... > &src, std::string const &name="", typename std::enable_if< std::is_same< typename ViewTraits< T, P... >::specialize, Kokkos::Experimental::Impl::ViewPCEContiguous >::value &&Impl::MirrorViewType< Space, T, P... >::is_same_memspace >::type *=nullptr)
Stokhos::CrsMatrix< ValueType, Device, Layout >::HostMirror create_mirror(const Stokhos::CrsMatrix< ValueType, Device, Layout > &A)
ConstructDestructFunctor< ExecSpace > create_functor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned vector_size) const