Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KokkosExp_View_Fad.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP
11 #define KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP
12 
13 #include "Sacado_ConfigDefs.h"
14 
15 #include "Kokkos_Core_fwd.hpp"
16 
17 #if (KOKKOS_VERSION > 40700) && !defined(KOKKOS_ENABLE_IMPL_VIEW_LEGACY) \
18  && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
19 #define SACADO_HAS_NEW_KOKKOS_VIEW_IMPL
20 #endif
21 
22 #ifdef SACADO_HAS_NEW_KOKKOS_VIEW_IMPL
24 #else
25 #if defined(HAVE_SACADO_KOKKOS)
26 
27 // Only include forward declarations so any overloads appear before they
28 // might be used inside Kokkos
29 #include "Kokkos_View_Fad_Fwd.hpp"
30 // We are hooking into Kokkos Core internals here
31 // Need to define this macro since we include non-public headers
32 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
33 #define KOKKOS_IMPL_PUBLIC_INCLUDE
34 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_CORE
35 #endif
36 #include "Kokkos_Layout.hpp"
37 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_CORE
38 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
39 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_CORE
40 #endif
41 
42 // Some definition that should exist whether the specializations exist or not
43 
44 namespace Kokkos {
45 
46 // Whether a given type is a view with Sacado FAD scalar type
47 template <typename view_type>
48 struct is_view_fad { static const bool value = false; };
49 
50 // Whether a given type is a view with Sacado FAD scalar type with contiguous
51 // layout
52 template <typename view_type>
53 struct is_view_fad_contiguous { static const bool value = false; };
54 
55 // Template function for extracting sacado dimension
56 template <typename view_type>
57 KOKKOS_INLINE_FUNCTION
58 constexpr unsigned
59 dimension_scalar(const view_type& /* view */) {
60  return 0;
61 }
62 
63 // Template function for extracting aligned sacado dimension
64 template <typename view_type>
65 KOKKOS_INLINE_FUNCTION
66 constexpr unsigned
67 dimension_scalar_aligned(const view_type& view) {
68  return dimension_scalar(view);
69 }
70 
71 }
72 
73 // Make sure the user really wants these View specializations
74 #if defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
75 
76 //----------------------------------------------------------------------------
77 
78 namespace Kokkos {
79 namespace Impl {
80 
81 struct ViewSpecializeSacadoFad {};
82 struct ViewSpecializeSacadoFadContiguous {};
83 
84 template< class ... Args >
85 struct is_ViewSpecializeSacadoFad { enum { value = false }; };
86 
87 template< class D , class ... P , class ... Args >
88 struct is_ViewSpecializeSacadoFad< Kokkos::View<D,P...> , Args... > {
89  enum { value =
90  std::is_same< typename Kokkos::ViewTraits<D,P...>::specialize
91  , ViewSpecializeSacadoFad >::value
92  &&
93  ( ( sizeof...(Args) == 0 ) ||
94  is_ViewSpecializeSacadoFad< Args... >::value ) };
95 };
96 
97 } // namespace Impl
98 } // namespace Kokkos
99 
100 namespace Kokkos {
101 
102 template <typename T, typename ... P>
103 struct is_view_fad< View<T,P...> > {
104  typedef View<T,P...> view_type;
105  static const bool value =
106  std::is_same< typename view_type::traits::specialize,
107  Impl::ViewSpecializeSacadoFad >::value ||
108  std::is_same< typename view_type::traits::specialize,
109  Impl::ViewSpecializeSacadoFadContiguous >::value;
110 };
111 
112 template <typename T, typename ... P>
113 struct is_view_fad_contiguous< View<T,P...> > {
114  typedef View<T,P...> view_type;
115  static const bool value =
116  std::is_same< typename view_type::traits::specialize,
117  Impl::ViewSpecializeSacadoFadContiguous >::value;
118 };
119 
120 }
121 
122 #include "Sacado_Traits.hpp"
123 #include "Kokkos_Core.hpp"
125 #include "Kokkos_LayoutNatural.hpp"
126 
127 namespace Kokkos {
128 namespace Impl {
129 
130 // Define our overload of view_copy above. Needs to happen after including
131 // Kokkos_Core.hpp since it calls the default implementation
132 template<class DT, class ... DP,
133  class ST, class ... SP>
134 typename std::enable_if< is_view_fad< Kokkos::View<DT,DP...> >::value &&
135  is_view_fad< Kokkos::View<ST,SP...> >::value
136  >::type
137 view_copy(const Kokkos::View<DT,DP...>& dst, const Kokkos::View<ST,SP...>& src)
138 {
139  typedef typename Kokkos::View<DT,DP...>::array_type dst_array_type;
140  typedef typename Kokkos::View<ST,SP...>::array_type src_array_type;
141  view_copy( dst_array_type(dst) , src_array_type(src) );
142 }
143 
144 template<class ExecutionSpace,
145  class DT, class ... DP,
146  class ST, class ... SP>
147 typename std::enable_if< is_view_fad< Kokkos::View<DT,DP...> >::value &&
148  is_view_fad< Kokkos::View<ST,SP...> >::value
149  >::type
150 view_copy(const ExecutionSpace& space,
151  const Kokkos::View<DT,DP...>& dst, const Kokkos::View<ST,SP...>& src)
152 {
153  typedef typename Kokkos::View<DT,DP...>::array_type dst_array_type;
154  typedef typename Kokkos::View<ST,SP...>::array_type src_array_type;
155  view_copy( space, dst_array_type(dst) , src_array_type(src) );
156 }
157 
158 } // namespace Impl
159 } // namespace Kokkos
160 
161 namespace Kokkos {
162 
163 template <typename T, typename ... P>
164 KOKKOS_INLINE_FUNCTION
165 constexpr typename
166 std::enable_if< is_view_fad< View<T,P...> >::value, unsigned >::type
167 dimension_scalar(const View<T,P...>& view) {
168 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
169  return view.implementation_map().dimension_scalar();
170 #else
171  return view.impl_map().dimension_scalar();
172 #endif
173 }
174 
175 template <typename Layout>
176 struct ApplyNatural {
177  typedef LayoutNatural<Layout> type;
178 };
179 
180 template <typename Layout>
181 struct ApplyNatural< LayoutNatural<Layout> > {
182  typedef LayoutNatural<Layout> type;
183 };
184 
185 template < typename T, typename Enable = void >
186 struct ArrayScalar;
187 
188 template < typename T >
189 struct ArrayScalar< T, typename std::enable_if< !Sacado::IsFad<T>::value >::type > {
190  typedef T type;
191 };
192 
193 template < typename T >
194 struct ArrayScalar< T, typename std::enable_if< Sacado::IsFad<T>::value >::type > {
195  typedef typename ArrayScalar< typename Sacado::ValueType<T>::type >::type* type;
196 };
197 
198 
199 template < typename DataType, int Rank >
200 struct AppendRankToConvertedFad {
201  static_assert( Rank > -1, "Sacado AppendRankToConvertedFad Error: Rank < 0" );
202  typedef typename AppendRankToConvertedFad<DataType,Rank-1>::type* type;
203 };
204 
205 // terminating specialization
206 template < typename DataType >
207 struct AppendRankToConvertedFad< DataType, 0 > {
208  typedef DataType type;
209 };
210 
211 
212 template < class ArrayLayout, class Enable = void >
213 struct ViewArrayLayoutSelector;
214 
215 template < class ArrayLayout >
216 struct ViewArrayLayoutSelector< ArrayLayout, typename std::enable_if< std::is_same<ArrayLayout, Kokkos::LayoutLeft>::value >::type >
217 {
218  using type = Kokkos::LayoutLeft;
219 };
220 
221 template < class ArrayLayout >
222 struct ViewArrayLayoutSelector< ArrayLayout, typename std::enable_if< std::is_same<ArrayLayout, Kokkos::LayoutRight>::value >::type >
223 {
224  using type = Kokkos::LayoutRight;
225 };
226 
227 template < class ArrayLayout >
228 struct ViewArrayLayoutSelector< ArrayLayout, typename std::enable_if< std::is_same<ArrayLayout, Kokkos::LayoutStride>::value >::type >
229 {
230  using type = Kokkos::LayoutStride;
231 };
232 
233 template < typename ViewType, typename Enable = void >
234 struct PODViewDeepCopyType;
235 
236 template < typename ViewType >
237 struct PODViewDeepCopyType< ViewType, typename std::enable_if< is_view_fad<ViewType>::value >::type >
238 {
239 
240  typedef ViewType view_type;
241  typedef typename ArrayScalar< typename view_type::value_type >::type fad_converted_type;
242  typedef typename AppendRankToConvertedFad< fad_converted_type, view_type::rank >::type new_data_type;
243 
244  typedef typename ViewArrayLayoutSelector<typename view_type::array_layout>::type layout;
245  //typedef typename view_type::array_layout layout;
246  typedef typename view_type::device_type device;
247  typedef typename view_type::memory_traits memory;
248 
249  typedef Kokkos::View< new_data_type, layout, device, memory > type;
250 };
251 
252 // Not a Fad type
253 template < typename ViewType >
254 struct PODViewDeepCopyType< ViewType, typename std::enable_if< !is_view_fad<ViewType>::value >::type >
255 {
256  typedef ViewType type;
257 };
258 
259 
260 template <typename ViewType, typename Enabled = void>
261 struct NaturalArrayType {
262  typedef ViewType type;
263 };
264 
265 template <typename D, typename ... P>
266 struct NaturalArrayType< View<D,P...>,
267  typename std::enable_if< is_view_fad< View<D,P...> >::value >::type > {
268  typedef View<D,P...> view_type;
269  typedef typename view_type::data_type data_type;
270  typedef typename view_type::array_layout layout;
271  typedef typename view_type::device_type device;
272  typedef typename view_type::memory_traits memory;
273  //typedef typename ApplyNatural<layout>::type natural_layout;
274  typedef typename ViewArrayLayoutSelector<layout>::type natural_layout;
275  typedef View<data_type,natural_layout,device,memory> type;
276 };
277 
278 namespace Impl {
279 
280 template <class OutputView, typename Enabled = void>
281 struct SacadoViewFill
282 {
283  typedef typename OutputView::const_value_type const_value_type ;
284  typedef typename OutputView::execution_space execution_space ;
285 
286  const OutputView output ;
287  const_value_type input ;
288 
289  KOKKOS_INLINE_FUNCTION
290  void operator()( const size_t i0 ) const
291  {
292  const size_t n1 = output.extent(1);
293  const size_t n2 = output.extent(2);
294  const size_t n3 = output.extent(3);
295  const size_t n4 = output.extent(4);
296  const size_t n5 = output.extent(5);
297  const size_t n6 = output.extent(6);
298 
299  for ( size_t i1 = 0 ; i1 < n1 ; ++i1 ) {
300  for ( size_t i2 = 0 ; i2 < n2 ; ++i2 ) {
301  for ( size_t i3 = 0 ; i3 < n3 ; ++i3 ) {
302  for ( size_t i4 = 0 ; i4 < n4 ; ++i4 ) {
303  for ( size_t i5 = 0 ; i5 < n5 ; ++i5 ) {
304  for ( size_t i6 = 0 ; i6 < n6 ; ++i6 ) {
305  output.access(i0,i1,i2,i3,i4,i5,i6) = input ;
306  }}}}}}
307  }
308 
309  SacadoViewFill( const OutputView & arg_out , const_value_type & arg_in )
310  : output( arg_out ), input( arg_in )
311  {
312  const size_t n0 = output.extent(0);
313  Kokkos::RangePolicy<execution_space> policy( 0, n0 );
314  Kokkos::parallel_for( policy, *this );
315  }
316 };
317 
318 }
319 
320 // Overload of deep_copy for Fad views intializing to a constant scalar
321 template< class DT, class ... DP >
322 void deep_copy(
323  const View<DT,DP...> & view ,
324  const typename Sacado::ScalarType< typename View<DT,DP...>::value_type >::type & value
325  , typename std::enable_if<(
326  std::is_same< typename ViewTraits<DT,DP...>::specialize
327  , Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
328  std::is_same< typename ViewTraits<DT,DP...>::specialize
329  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value
330  )>::type * = 0 )
331 {
332  static_assert(
333  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
334  typename ViewTraits<DT,DP...>::non_const_value_type >::value
335  , "Can only deep copy into non-const type" );
336 
337  Impl::SacadoViewFill< View<DT,DP...> >( view , value );
338 }
339 
340 
341 // Overload of deep_copy for Fad views intializing to a constant Fad
342 template< class DT, class ... DP >
343 void deep_copy(
344  const View<DT,DP...> & view ,
345  const typename View<DT,DP...>::value_type & value
346  , typename std::enable_if<(
347  std::is_same< typename ViewTraits<DT,DP...>::specialize
348  , Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
349  std::is_same< typename ViewTraits<DT,DP...>::specialize
350  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value
351  )>::type * = 0 )
352 {
353  static_assert(
354  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
355  typename ViewTraits<DT,DP...>::non_const_value_type >::value
356  , "Can only deep copy into non-const type" );
357 
358  Impl::SacadoViewFill< View<DT,DP...> >( view , value );
359 }
360 
361 /* Specialize for deep copy of FAD */
362 template< class ExecSpace, class DT , class ... DP , class ST , class ... SP >
363 inline
364 void deep_copy( const ExecSpace &,
365  const View<DT,DP...> & dst ,
366  const View<ST,SP...> & src
367  , typename std::enable_if<(
368  ( std::is_same< typename ViewTraits<DT,DP...>::specialize
369  , Kokkos::Impl::ViewSpecializeSacadoFad >::value
370  ||
371  std::is_same< typename ViewTraits<DT,DP...>::specialize
372  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
373  &&
374  ( std::is_same< typename ViewTraits<ST,SP...>::specialize
375  , Kokkos::Impl::ViewSpecializeSacadoFad >::value
376  ||
377  std::is_same< typename ViewTraits<ST,SP...>::specialize
378  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
379  )>::type * = 0 )
380 {
381  static_assert(
382  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
383  typename ViewTraits<DT,DP...>::non_const_value_type >::value
384  , "Deep copy destination must be non-const" );
385 
386  static_assert(
387  ( unsigned(ViewTraits<DT,DP...>::rank) ==
388  unsigned(ViewTraits<ST,SP...>::rank) )
389  , "Deep copy destination and source must have same rank" );
390 
391 #if 0
392  // Current impl
393  typedef typename View<DT,DP...>::array_type dst_array_type;
394  typedef typename View<ST,SP...>::array_type src_array_type;
395  typename NaturalArrayType< dst_array_type >::type dst_array( dst );
396  typename NaturalArrayType< src_array_type >::type src_array( src );
397 #else
398  // Copy-assign Views of FadType to Kokkos Views to use Kokkos' deep_copy routine
399  typename PODViewDeepCopyType< View<DT,DP...> >::type dst_array( dst );
400  typename PODViewDeepCopyType< View<ST,SP...> >::type src_array( src );
401 #endif
402  Kokkos::deep_copy( ExecSpace(), dst_array , src_array );
403 }
404 
405 /* Specialize for deep copy of FAD */
406 template< class DT , class ... DP , class ST , class ... SP >
407 inline
408 void deep_copy( const View<DT,DP...> & dst ,
409  const View<ST,SP...> & src
410  , typename std::enable_if<(
411  ( std::is_same< typename ViewTraits<DT,DP...>::specialize
412  , Kokkos::Impl::ViewSpecializeSacadoFad >::value
413  ||
414  std::is_same< typename ViewTraits<DT,DP...>::specialize
415  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
416  &&
417  ( std::is_same< typename ViewTraits<ST,SP...>::specialize
418  , Kokkos::Impl::ViewSpecializeSacadoFad >::value
419  ||
420  std::is_same< typename ViewTraits<ST,SP...>::specialize
421  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
422  )>::type * = 0 )
423 {
424  using exec_space = typename View<DT,DP...>::execution_space;
425  Kokkos::fence();
426  Kokkos::deep_copy(exec_space(), dst, src);
427  Kokkos::fence();
428 }
429 
430 template< class T , class ... P >
431 inline
432 typename std::enable_if<
433  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
434  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
435  std::is_same< typename ViewTraits<T,P...>::specialize ,
436  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ) &&
437  !std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
438  Kokkos::LayoutStride >::value,
439  typename Kokkos::View<T,P...>::host_mirror_type>::type
440 create_mirror(const Kokkos::View<T,P...> & src)
441 {
442  typedef View<T,P...> src_type ;
443  typedef typename src_type::host_mirror_type dst_type ;
444 
445  typename src_type::array_layout layout = src.layout();
446  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
447 
448  return dst_type(std::string(src.label()).append("_mirror"), layout);
449 }
450 
451 template< class T , class ... P >
452 inline
453 typename std::enable_if<
454  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
455  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
456  std::is_same< typename ViewTraits<T,P...>::specialize ,
457  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ) &&
458  std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
459  Kokkos::LayoutStride >::value,
460  typename Kokkos::View<T,P...>::host_mirror_type>::type
461 create_mirror(const Kokkos::View<T,P...> & src)
462 {
463  typedef View<T,P...> src_type ;
464  typedef typename src_type::array_type src_array_type ;
465  typedef typename src_type::host_mirror_type dst_type ;
466 
467  Kokkos::LayoutStride layout ;
468 
469  // Use dimensions/strides from array_type to get hidden dim/stride
470  src_array_type src_array = src;
471  layout.dimension[0] = src_array.extent(0);
472  layout.dimension[1] = src_array.extent(1);
473  layout.dimension[2] = src_array.extent(2);
474  layout.dimension[3] = src_array.extent(3);
475  layout.dimension[4] = src_array.extent(4);
476  layout.dimension[5] = src_array.extent(5);
477  layout.dimension[6] = src_array.extent(6);
478  layout.dimension[7] = src_array.extent(7);
479 
480  layout.stride[0] = src_array.stride_0();
481  layout.stride[1] = src_array.stride_1();
482  layout.stride[2] = src_array.stride_2();
483  layout.stride[3] = src_array.stride_3();
484  layout.stride[4] = src_array.stride_4();
485  layout.stride[5] = src_array.stride_5();
486  layout.stride[6] = src_array.stride_6();
487  layout.stride[7] = src_array.stride_7();
488 
489  return dst_type(std::string(src.label()).append("_mirror"), layout);
490 }
491 
492 template<class Space, class T, class ... P, typename Enabled>
493 typename std::enable_if<
494  std::is_same< typename ViewTraits<T,P...>::specialize ,
495  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
496  std::is_same< typename ViewTraits<T,P...>::specialize ,
497  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value,
498  typename Impl::MirrorViewType<Space,T,P ...>::dest_view_type>::type
499 create_mirror(const Space& , const Kokkos::View<T,P...> & src)
500 {
501  typedef View<T,P...> src_type ;
502  typename src_type::array_layout layout = src.layout();
503  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
504  return typename Impl::MirrorViewType<Space,T,P ...>::dest_view_type(src.label(),layout);
505 }
506 
507 template< class T , class ... P >
508 inline
509 typename std::enable_if<
510  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
511  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
512  std::is_same< typename ViewTraits<T,P...>::specialize ,
513  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ) &&
514  !std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
515  Kokkos::LayoutStride >::value,
516  typename Kokkos::View<T,P...>::host_mirror_type>::type
517 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
518  const Kokkos::View<T,P...> & src)
519 {
520  typedef View<T,P...> src_type ;
521  typedef typename src_type::host_mirror_type dst_type ;
522 
523  typename src_type::array_layout layout = src.layout();
524  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
525 
526  return dst_type(
527  Kokkos::view_alloc(std::string(src.label()).append("_mirror"), wi), layout);
528 }
529 
530 template< class T , class ... P >
531 inline
532 typename std::enable_if<
533  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
534  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
535  std::is_same< typename ViewTraits<T,P...>::specialize ,
536  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ) &&
537  std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout,
538  Kokkos::LayoutStride >::value,
539  typename Kokkos::View<T,P...>::host_mirror_type>::type
540 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
541  const Kokkos::View<T,P...> & src)
542 {
543  typedef View<T,P...> src_type ;
544  typedef typename src_type::array_type src_array_type ;
545  typedef typename src_type::host_mirror_type dst_type ;
546 
547  Kokkos::LayoutStride layout ;
548 
549  // Use dimensions/strides from array_type to get hidden dim/stride
550  src_array_type src_array = src;
551  layout.dimension[0] = src_array.extent(0);
552  layout.dimension[1] = src_array.extent(1);
553  layout.dimension[2] = src_array.extent(2);
554  layout.dimension[3] = src_array.extent(3);
555  layout.dimension[4] = src_array.extent(4);
556  layout.dimension[5] = src_array.extent(5);
557  layout.dimension[6] = src_array.extent(6);
558  layout.dimension[7] = src_array.extent(7);
559 
560  layout.stride[0] = src_array.stride_0();
561  layout.stride[1] = src_array.stride_1();
562  layout.stride[2] = src_array.stride_2();
563  layout.stride[3] = src_array.stride_3();
564  layout.stride[4] = src_array.stride_4();
565  layout.stride[5] = src_array.stride_5();
566  layout.stride[6] = src_array.stride_6();
567  layout.stride[7] = src_array.stride_7();
568 
569  return dst_type(
570  Kokkos::view_alloc(std::string(src.label()).append("_mirror"), wi), layout);
571 }
572 
573 template<class Space, class T, class ... P, typename Enable>
574 typename std::enable_if<
575  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
576  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
577  std::is_same< typename ViewTraits<T,P...>::specialize ,
578  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ),
579  typename Impl::MirrorViewType<Space,T,P ...>::dest_view_type>::type
580 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
581  const Space& , const Kokkos::View<T,P...> & src)
582 {
583  typedef View<T,P...> src_type ;
584  typename src_type::array_layout layout = src.layout();
585  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
586  return typename Impl::MirrorViewType<Space,T,P ...>::dest_view_type(
587  Kokkos::view_alloc(src.label(), wi), layout);
588 }
589 
590 template <class Space, class T, class... P>
591 typename Impl::MirrorViewType<Space, T, P...>::view_type
592 create_mirror_view_and_copy(
593  const Space&, const Kokkos::View<T, P...>& src,
594  std::string const& name,
595  typename std::enable_if<
596  ( std::is_same<typename ViewTraits<T, P...>::specialize,
597  Kokkos::Impl::ViewSpecializeSacadoFad>::value ||
598  std::is_same< typename ViewTraits<T,P...>::specialize ,
599  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ) &&
600  Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type*)
601 {
602  (void)name;
603  fence(
604  "Kokkos::create_mirror_view_and_copy: fence before returning src view"); // same behavior as deep_copy(src, src)
605  return src;
606 }
607 
608 template <class Space, class T, class... P>
609 typename Impl::MirrorViewType<Space, T, P...>::view_type
610 create_mirror_view_and_copy(
611  const Space&, const Kokkos::View<T, P...>& src,
612  std::string const& name,
613  typename std::enable_if<
614  ( std::is_same<typename ViewTraits<T, P...>::specialize,
615  Kokkos::Impl::ViewSpecializeSacadoFad>::value ||
616  std::is_same< typename ViewTraits<T,P...>::specialize ,
617  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value ) &&
618  !Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type*)
619 {
620  using src_type = View<T,P...>;
621  using Mirror = typename Impl::MirrorViewType<Space, T, P...>::view_type;
622  std::string label = name.empty() ? src.label() : name;
623  typename src_type::array_layout layout = src.layout();
624  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
625  auto mirror = typename Mirror::non_const_type{
626  view_alloc(WithoutInitializing, label), layout};
627  deep_copy(mirror, src);
628  return mirror;
629 }
630 
631 namespace Impl {
632 
633 template <unsigned N, typename... Args>
634 KOKKOS_FUNCTION std::enable_if_t<
635  N == View<Args...>::Rank &&
636  (std::is_same<typename ViewTraits<Args...>::specialize,
637  Kokkos::Impl::ViewSpecializeSacadoFad>::value ||
638  std::is_same<typename ViewTraits<Args...>::specialize,
639  Kokkos::Impl::ViewSpecializeSacadoFadContiguous>::value),
640  View<Args...>>
641 as_view_of_rank_n(View<Args...> v) {
642  return v;
643 }
644 
645 // Placeholder implementation to compile generic code for DynRankView; should
646 // never be called
647 template <unsigned N, typename T, typename... Args>
648 std::enable_if_t<
649  N != View<T, Args...>::Rank &&
650  (std::is_same<typename ViewTraits<T, Args...>::specialize,
651  Kokkos::Impl::ViewSpecializeSacadoFad>::value ||
652  std::is_same<typename ViewTraits<T, Args...>::specialize,
653  Kokkos::Impl::ViewSpecializeSacadoFadContiguous>::value),
654  View<typename RankDataType<typename View<T, Args...>::value_type, N>::type,
655  Args...>>
656 as_view_of_rank_n(View<T, Args...>) {
657  Kokkos::Impl::throw_runtime_exception(
658  "Trying to get at a View of the wrong rank");
659  return {};
660 }
661 
662 }
663 
664 } // namespace Kokkos
665 
666 namespace Kokkos {
667 namespace Experimental {
668 
669 template <class DT, class... DP>
670 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
671  const View<DT, DP...>& dst,
672  typename ViewTraits<DT, DP...>::const_value_type& value,
673  typename std::enable_if<(
674  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
675  Kokkos::Impl::ViewSpecializeSacadoFad >::value
676  ||
677  std::is_same< typename ViewTraits<DT,DP...>::specialize,
678  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
679  && (unsigned(ViewTraits<DT, DP...>::rank) == 1))>::type*)
680 {
681  if (dst.data() == nullptr)
682  return;
683 
684  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
685  dst(i0) = value;
686 }
687 
688 template <class DT, class... DP>
689 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
690  const View<DT, DP...>& dst,
691  typename ViewTraits<DT, DP...>::const_value_type& value,
692  typename std::enable_if<(
693  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
694  Kokkos::Impl::ViewSpecializeSacadoFad >::value
695  ||
696  std::is_same< typename ViewTraits<DT,DP...>::specialize,
697  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
698  && (unsigned(ViewTraits<DT, DP...>::rank) == 2))>::type*)
699 {
700  if (dst.data() == nullptr)
701  return;
702 
703  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
704  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
705  dst(i0,i1) = value;
706 }
707 
708 template <class DT, class... DP>
709 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
710  const View<DT, DP...>& dst,
711  typename ViewTraits<DT, DP...>::const_value_type& value,
712  typename std::enable_if<(
713  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
714  Kokkos::Impl::ViewSpecializeSacadoFad >::value
715  ||
716  std::is_same< typename ViewTraits<DT,DP...>::specialize,
717  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
718  && (unsigned(ViewTraits<DT, DP...>::rank) == 3))>::type*)
719 {
720  if (dst.data() == nullptr)
721  return;
722 
723  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
724  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
725  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
726  dst(i0,i1,i2) = value;
727 }
728 
729 template <class DT, class... DP>
730 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
731  const View<DT, DP...>& dst,
732  typename ViewTraits<DT, DP...>::const_value_type& value,
733  typename std::enable_if<(
734  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
735  Kokkos::Impl::ViewSpecializeSacadoFad >::value
736  ||
737  std::is_same< typename ViewTraits<DT,DP...>::specialize,
738  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
739  && (unsigned(ViewTraits<DT, DP...>::rank) == 4))>::type*)
740 {
741  if (dst.data() == nullptr)
742  return;
743 
744  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
745  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
746  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
747  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
748  dst(i0,i1,i2,i3) = value;
749 }
750 
751 template <class DT, class... DP>
752 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
753  const View<DT, DP...>& dst,
754  typename ViewTraits<DT, DP...>::const_value_type& value,
755  typename std::enable_if<(
756  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
757  Kokkos::Impl::ViewSpecializeSacadoFad >::value
758  ||
759  std::is_same< typename ViewTraits<DT,DP...>::specialize,
760  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
761  && (unsigned(ViewTraits<DT, DP...>::rank) == 5))>::type*)
762 {
763  if (dst.data() == nullptr)
764  return;
765 
766  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
767  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
768  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
769  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
770  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
771  dst(i0,i1,i2,i3,i4) = value;
772 }
773 
774 template <class DT, class... DP>
775 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
776  const View<DT, DP...>& dst,
777  typename ViewTraits<DT, DP...>::const_value_type& value,
778  typename std::enable_if<(
779  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
780  Kokkos::Impl::ViewSpecializeSacadoFad >::value
781  ||
782  std::is_same< typename ViewTraits<DT,DP...>::specialize,
783  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
784  && (unsigned(ViewTraits<DT, DP...>::rank) == 6))>::type*)
785 {
786  if (dst.data() == nullptr)
787  return;
788 
789  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
790  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
791  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
792  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
793  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
794  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
795  dst(i0,i1,i2,i3,i4,i5) = value;
796 }
797 
798 template <class DT, class... DP>
799 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
800  const View<DT, DP...>& dst,
801  typename ViewTraits<DT, DP...>::const_value_type& value,
802  typename std::enable_if<(
803  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
804  Kokkos::Impl::ViewSpecializeSacadoFad >::value
805  ||
806  std::is_same< typename ViewTraits<DT,DP...>::specialize,
807  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
808  && (unsigned(ViewTraits<DT, DP...>::rank) == 7))>::type*)
809 {
810  if (dst.data() == nullptr)
811  return;
812 
813  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
814  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
815  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
816  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
817  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
818  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
819  for (size_t i6 = 0; i6 < dst.extent(6); ++i6)
820  dst(i0,i1,i2,i3,i4,i5,i6) = value;
821 }
822 
823 template <class TeamType, class DT, class... DP>
824 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
825  const TeamType& team, const View<DT, DP...>& dst,
826  typename ViewTraits<DT, DP...>::const_value_type& value,
827  typename std::enable_if<(
828  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
829  Kokkos::Impl::ViewSpecializeSacadoFad >::value
830  ||
831  std::is_same< typename ViewTraits<DT,DP...>::specialize,
832  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
833  && (unsigned(ViewTraits<DT, DP...>::rank) == 1))>::type*)
834 {
835  if (dst.data() == nullptr)
836  return;
837 
838  const size_t N = dst.extent(0);
839 
840  team.team_barrier();
841  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N),
842  [&](const int& i) { dst(i) = value; });
843  team.team_barrier();
844 }
845 
846 template <class TeamType, class DT, class... DP>
847 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
848  const TeamType& team, const View<DT, DP...>& dst,
849  typename ViewTraits<DT, DP...>::const_value_type& value,
850  typename std::enable_if<(
851  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
852  Kokkos::Impl::ViewSpecializeSacadoFad >::value
853  ||
854  std::is_same< typename ViewTraits<DT,DP...>::specialize,
855  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
856  && (unsigned(ViewTraits<DT, DP...>::rank) == 2))>::type*)
857 {
858  if (dst.data() == nullptr)
859  return;
860 
861  const size_t N = dst.extent(0) * dst.extent(1);
862 
863  team.team_barrier();
864  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
865  int i0 = i % dst.extent(0);
866  int i1 = i / dst.extent(0);
867  dst(i0, i1) = value;
868  });
869  team.team_barrier();
870 }
871 
872 template <class TeamType, class DT, class... DP>
873 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
874  const TeamType& team, const View<DT, DP...>& dst,
875  typename ViewTraits<DT, DP...>::const_value_type& value,
876  typename std::enable_if<(
877  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
878  Kokkos::Impl::ViewSpecializeSacadoFad >::value
879  ||
880  std::is_same< typename ViewTraits<DT,DP...>::specialize,
881  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
882  && (unsigned(ViewTraits<DT, DP...>::rank) == 3))>::type*)
883 {
884  if (dst.data() == nullptr)
885  return;
886 
887  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2);
888 
889  team.team_barrier();
890  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
891  int i0 = i % dst.extent(0);
892  int itmp = i / dst.extent(0);
893  int i1 = itmp % dst.extent(1);
894  int i2 = itmp / dst.extent(1);
895  dst(i0, i1, i2) = value;
896  });
897  team.team_barrier();
898 }
899 
900 template <class TeamType, class DT, class... DP>
901 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
902  const TeamType& team, const View<DT, DP...>& dst,
903  typename ViewTraits<DT, DP...>::const_value_type& value,
904  typename std::enable_if<(
905  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
906  Kokkos::Impl::ViewSpecializeSacadoFad >::value
907  ||
908  std::is_same< typename ViewTraits<DT,DP...>::specialize,
909  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
910  && (unsigned(ViewTraits<DT, DP...>::rank) == 4))>::type*)
911 {
912  if (dst.data() == nullptr)
913  return;
914 
915  const size_t N =
916  dst.extent(0) * dst.extent(1) * dst.extent(2) * dst.extent(3);
917 
918  team.team_barrier();
919  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
920  int i0 = i % dst.extent(0);
921  int itmp = i / dst.extent(0);
922  int i1 = itmp % dst.extent(1);
923  itmp = itmp / dst.extent(1);
924  int i2 = itmp % dst.extent(2);
925  int i3 = itmp / dst.extent(2);
926  dst(i0, i1, i2, i3) = value;
927  });
928  team.team_barrier();
929 }
930 
931 template <class TeamType, class DT, class... DP>
932 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
933  const TeamType& team, const View<DT, DP...>& dst,
934  typename ViewTraits<DT, DP...>::const_value_type& value,
935  typename std::enable_if<(
936  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
937  Kokkos::Impl::ViewSpecializeSacadoFad >::value
938  ||
939  std::is_same< typename ViewTraits<DT,DP...>::specialize,
940  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
941  && (unsigned(ViewTraits<DT, DP...>::rank) == 5))>::type*)
942 {
943  if (dst.data() == nullptr)
944  return;
945 
946  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
947  dst.extent(3) * dst.extent(4);
948 
949  team.team_barrier();
950  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
951  int i0 = i % dst.extent(0);
952  int itmp = i / dst.extent(0);
953  int i1 = itmp % dst.extent(1);
954  itmp = itmp / dst.extent(1);
955  int i2 = itmp % dst.extent(2);
956  itmp = itmp / dst.extent(2);
957  int i3 = itmp % dst.extent(3);
958  int i4 = itmp / dst.extent(3);
959  dst(i0, i1, i2, i3, i4) = value;
960  });
961  team.team_barrier();
962 }
963 
964 template <class TeamType, class DT, class... DP>
965 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
966  const TeamType& team, const View<DT, DP...>& dst,
967  typename ViewTraits<DT, DP...>::const_value_type& value,
968  typename std::enable_if<(
969  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
970  Kokkos::Impl::ViewSpecializeSacadoFad >::value
971  ||
972  std::is_same< typename ViewTraits<DT,DP...>::specialize,
973  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
974  && (unsigned(ViewTraits<DT, DP...>::rank) == 6))>::type*)
975 {
976  if (dst.data() == nullptr)
977  return;
978 
979  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
980  dst.extent(3) * dst.extent(4) * dst.extent(5);
981 
982  team.team_barrier();
983  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
984  int i0 = i % dst.extent(0);
985  int itmp = i / dst.extent(0);
986  int i1 = itmp % dst.extent(1);
987  itmp = itmp / dst.extent(1);
988  int i2 = itmp % dst.extent(2);
989  itmp = itmp / dst.extent(2);
990  int i3 = itmp % dst.extent(3);
991  itmp = itmp / dst.extent(3);
992  int i4 = itmp % dst.extent(4);
993  int i5 = itmp / dst.extent(4);
994  dst(i0, i1, i2, i3, i4, i5) = value;
995  });
996  team.team_barrier();
997 }
998 
999 template <class TeamType, class DT, class... DP>
1000 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
1001  const TeamType& team, const View<DT, DP...>& dst,
1002  typename ViewTraits<DT, DP...>::const_value_type& value,
1003  typename std::enable_if<(
1004  ( std::is_same< typename ViewTraits<DT,DP...>::specialize,
1005  Kokkos::Impl::ViewSpecializeSacadoFad >::value
1006  ||
1007  std::is_same< typename ViewTraits<DT,DP...>::specialize,
1008  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
1009  && (unsigned(ViewTraits<DT, DP...>::rank) == 7))>::type*)
1010 {
1011  if (dst.data() == nullptr)
1012  return;
1013 
1014  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
1015  dst.extent(3) * dst.extent(4) * dst.extent(5) *
1016  dst.extent(6);
1017 
1018  team.team_barrier();
1019  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1020  int i0 = i % dst.extent(0);
1021  int itmp = i / dst.extent(0);
1022  int i1 = itmp % dst.extent(1);
1023  itmp = itmp / dst.extent(1);
1024  int i2 = itmp % dst.extent(2);
1025  itmp = itmp / dst.extent(2);
1026  int i3 = itmp % dst.extent(3);
1027  itmp = itmp / dst.extent(3);
1028  int i4 = itmp % dst.extent(4);
1029  itmp = itmp / dst.extent(4);
1030  int i5 = itmp % dst.extent(5);
1031  int i6 = itmp / dst.extent(5);
1032  dst(i0, i1, i2, i3, i4, i5, i6) = value;
1033  });
1034  team.team_barrier();
1035 }
1036 
1037 } // namespace Experimental
1038 } // namespace Kokkos
1039 
1040 //----------------------------------------------------------------------------
1041 
1042 namespace Kokkos {
1043 namespace Impl {
1044 
1045 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
1046 struct FadViewDataAnalysis
1047 {
1048 private:
1049 
1050  typedef ViewArrayAnalysis< DataType > array_analysis ;
1051 
1052 public:
1053 
1054  // Specialized view data mapping:
1055  typedef ViewSpecializeSacadoFad specialize ;
1056 
1057  typedef typename array_analysis::dimension dimension ;
1058  typedef typename array_analysis::value_type value_type ;
1059  typedef typename array_analysis::const_value_type const_value_type ;
1060  typedef typename array_analysis::non_const_value_type non_const_value_type ;
1061 
1062  // Generate analogous multidimensional array specification type.
1063  typedef typename
1064  ViewDataType< value_type , dimension >::type type ;
1065  typedef typename
1066  ViewDataType< const_value_type , dimension >::type const_type ;
1067  typedef typename
1068  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
1069 
1070 private:
1071 
1072  // A const ?
1074 
1075  // The unwrapped scalar types:
1076  typedef typename
1077  std::conditional< is_const , const ScalarType , ScalarType >::type
1078  scalar_type ;
1079 
1080  typedef ScalarType non_const_scalar_type ;
1081  typedef const ScalarType const_scalar_type ;
1082 
1083  // Append the FAD static dimension
1084  typedef typename array_analysis::dimension::
1085  template append<( DimFad ? DimFad + 1 : 0 )>::type
1086  scalar_dimension ;
1087 
1088 public:
1089 
1090  // Generate "flattened" multidimensional array specification type.
1091  typedef typename
1092  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
1093 
1094  typedef typename
1095  ViewDataType< const_scalar_type , scalar_dimension >::type
1096  const_scalar_array_type ;
1097 
1098  typedef typename
1099  ViewDataType< non_const_scalar_type , scalar_dimension >::type
1100  non_const_scalar_array_type ;
1101 };
1102 
1103 // Specialization for LayoutContiguous, where the Fad type is kept contiguous.
1104 // This requires a separate view specialization.
1105 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad, unsigned Stride >
1106 struct FadViewDataAnalysis<DataType, LayoutContiguous<ArrayLayout,Stride>, ScalarType, DimFad>
1107 {
1108 private:
1109 
1110  typedef ViewArrayAnalysis< DataType > array_analysis ;
1111 
1112 public:
1113 
1114  // For now use the default mapping
1115  typedef ViewSpecializeSacadoFadContiguous specialize ;
1116 
1117  typedef typename array_analysis::dimension dimension ;
1118  typedef typename array_analysis::value_type value_type ;
1119  typedef typename array_analysis::const_value_type const_value_type ;
1120  typedef typename array_analysis::non_const_value_type non_const_value_type ;
1121 
1122  // Generate analogous multidimensional array specification type.
1123  typedef typename
1124  ViewDataType< value_type , dimension >::type type ;
1125  typedef typename
1126  ViewDataType< const_value_type , dimension >::type const_type ;
1127  typedef typename
1128  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
1129 
1130 private:
1131 
1132  // A const ?
1134 
1135  // The unwrapped scalar types:
1136  typedef typename
1137  std::conditional< is_const , const ScalarType , ScalarType >::type
1138  scalar_type ;
1139 
1140  typedef ScalarType non_const_scalar_type ;
1141  typedef const ScalarType const_scalar_type ;
1142 
1143  // Prepend/append the FAD dimension
1144  typedef typename std::conditional<
1146  typename array_analysis::dimension::
1147  template prepend<0>::type,
1148  typename array_analysis::dimension::
1149  template append<0>::type >::type
1150  scalar_dimension ;
1151 
1152 public:
1153 
1154  // Generate "flattened" multidimensional array specification type.
1155  typedef typename
1156  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
1157 
1158  typedef typename
1159  ViewDataType< const_scalar_type , scalar_dimension >::type
1160  const_scalar_array_type ;
1161 
1162  typedef typename
1163  ViewDataType< non_const_scalar_type , scalar_dimension >::type
1164  non_const_scalar_array_type ;
1165 
1166 };
1167 
1168 // Specialization for LayoutNatural, where we don't allow striding within
1169 // the FadType.
1170 //
1171 // Currently this is implemented by choosing the default ViewMapping
1172 // specialization.
1173 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
1174 struct FadViewDataAnalysis<DataType, LayoutNatural<ArrayLayout>, ScalarType, DimFad>
1175 {
1176 private:
1177 
1178  typedef ViewArrayAnalysis< DataType > array_analysis ;
1179 
1180 public:
1181 
1182  // For now use the default mapping
1183  typedef void specialize ;
1184 
1185  typedef typename array_analysis::dimension dimension ;
1186  typedef typename array_analysis::value_type value_type ;
1187  typedef typename array_analysis::const_value_type const_value_type ;
1188  typedef typename array_analysis::non_const_value_type non_const_value_type ;
1189 
1190  // Generate analogous multidimensional array specification type.
1191  typedef typename
1192  ViewDataType< value_type , dimension >::type type ;
1193  typedef typename
1194  ViewDataType< const_value_type , dimension >::type const_type ;
1195  typedef typename
1196  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
1197 
1198  // Generate "flattened" multidimensional array specification type.
1199  typedef type scalar_array_type ;
1200  typedef const_type const_scalar_array_type ;
1201  typedef non_const_type non_const_scalar_array_type ;
1202 
1203 };
1204 
1205 } // namespace Impl
1206 } // namespace Kokkos
1207 
1208 //----------------------------------------------------------------------------
1209 
1210 namespace Sacado {
1211 
1212 namespace Fad { namespace Exp { template< typename > class GeneralFad ; } }
1213 
1214 #ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
1215 namespace Fad { template< typename > class DFad ; }
1216 namespace Fad { template< typename , int > class SFad ; }
1217 namespace Fad { template< typename , int > class SLFad ; }
1218 #endif
1219 
1220 namespace CacheFad { template< typename > class DFad ; }
1221 namespace ELRFad { template< typename > class DFad ; }
1222 namespace ELRCacheFad { template< typename > class DFad ; }
1223 
1224 namespace CacheFad { template< typename , int > class SFad ; }
1225 namespace ELRFad { template< typename , int > class SFad ; }
1226 namespace ELRCacheFad { template< typename , int > class SFad ; }
1227 
1228 
1229 namespace CacheFad { template< typename , int > class SLFad ; }
1230 namespace ELRFad { template< typename , int > class SLFad ; }
1231 namespace ELRCacheFad { template< typename , int > class SLFad ; }
1232 }
1233 
1234 namespace Kokkos {
1235 namespace Impl {
1236 
1237 #define KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( NS ) \
1238 template< class DataType , class ArrayLayout , typename ScalarType > \
1239 struct ViewDataAnalysis \
1240  < DataType /* Original view data type */ \
1241  , ArrayLayout \
1242  , Sacado:: NS ::DFad< ScalarType > \
1243  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , 0 > {}; \
1244 \
1245 template< class DataType , class ArrayLayout , typename ScalarType , int N > \
1246 struct ViewDataAnalysis \
1247  < DataType /* Original view data type */ \
1248  , ArrayLayout \
1249  , Sacado:: NS ::SFad< ScalarType , N > \
1250  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
1251  int(Sacado::StaticSize< Sacado:: NS ::SFad< ScalarType , N > >::value) \
1252  > {}; \
1253 \
1254 template< class DataType , class ArrayLayout , typename ScalarType , int N > \
1255 struct ViewDataAnalysis \
1256  < DataType /* Original view data type */ \
1257  , ArrayLayout \
1258  , Sacado:: NS ::SLFad< ScalarType , N > \
1259  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
1260  int(Sacado::StaticSize< Sacado:: NS ::SLFad< ScalarType , N > >::value) \
1261  > {}; \
1262 
1263 template< class DataType , class ArrayLayout , typename StorageType >
1264 struct ViewDataAnalysis
1265  < DataType /* Original view data type */
1266  , ArrayLayout
1267  , Sacado::Fad::Exp::GeneralFad< StorageType >
1268  > : public FadViewDataAnalysis< DataType, ArrayLayout, typename StorageType::value_type , 0 > {};
1269 
1270 #ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
1271 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( Fad )
1272 #endif
1273 
1274 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( CacheFad )
1275 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRFad )
1276 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRCacheFad )
1277 
1278 #undef KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD
1279 
1280 } // namespace Impl
1281 } // namespace Kokkos
1282 
1283 //----------------------------------------------------------------------------
1284 
1285 namespace Kokkos {
1286 
1287 // Copied from Sacado_ViewFactory
1288 template <class View, class ... ViewPack>
1289 KOKKOS_INLINE_FUNCTION
1290 unsigned dimension_scalar(const View& v, const ViewPack&... views) {
1291  const unsigned dim0 = dimension_scalar(v);
1292  const unsigned dim1 = dimension_scalar(views...);
1293  return dim0 >= dim1 ? dim0 : dim1 ;
1294 }
1295 
1296 } // namespace Kokkos
1297 
1298 //----------------------------------------------------------------------------
1299 
1300 namespace Kokkos { namespace Impl {
1301 
1302 template < typename Specialize, typename A, typename B >
1303 struct CommonViewValueType;
1304 
1305 template < typename A, typename B >
1306 struct CommonViewValueType< Kokkos::Impl::ViewSpecializeSacadoFad, A, B >
1307 {
1308  using value_type = typename Sacado::Promote<A,B>::type ;
1309 };
1310 
1311 template < typename A, typename B >
1312 struct CommonViewValueType< Kokkos::Impl::ViewSpecializeSacadoFadContiguous, A, B >
1313 {
1314  using value_type = typename Sacado::Promote<A,B>::type ;
1315 };
1316 
1317 
1318 template < class Specialize, class ValueType >
1319 struct CommonViewAllocProp;
1320 
1321 template < class ValueType >
1322 struct CommonViewAllocProp< Kokkos::Impl::ViewSpecializeSacadoFad, ValueType >
1323 {
1324  using value_type = ValueType;
1325  using scalar_array_type = typename Sacado::ValueType< value_type >::type;
1326  unsigned fad_dim;
1327  bool is_view_type;
1328 
1329  KOKKOS_INLINE_FUNCTION
1330  CommonViewAllocProp()
1331  : fad_dim(0) , is_view_type(false) {}
1332 
1333  // Assume all views are View or DynRankView
1334  // TODO If assumption is insufficient, better deduction on is_view...
1335  template < class View >
1336  KOKKOS_INLINE_FUNCTION
1337  CommonViewAllocProp( const View & view )
1338  : fad_dim ( dimension_scalar(view) )
1339  {
1341  }
1342 
1343  // TODO If assumption is insufficient, better deduction on is_view...
1344  template < class View, class ... Views >
1345  KOKKOS_INLINE_FUNCTION
1346  CommonViewAllocProp( const View & view, const Views & ... views )
1347  : fad_dim ( dimension_scalar(view, views... ) )
1348  {
1350  }
1351 
1352 };
1353 
1354 template < class ValueType >
1355 struct CommonViewAllocProp< Kokkos::Impl::ViewSpecializeSacadoFadContiguous, ValueType >
1356 {
1357  using value_type = ValueType;
1358  using scalar_array_type = typename Sacado::ValueType< value_type >::type;
1359  unsigned fad_dim;
1360  bool is_view_type;
1361 
1362  KOKKOS_INLINE_FUNCTION
1363  CommonViewAllocProp()
1364  : fad_dim(0) , is_view_type(false) {}
1365 
1366  // Assume all views are View or DynRankView
1367  // TODO If assumption is insufficient, better deduction on is_view...
1368  template < class View >
1369  KOKKOS_INLINE_FUNCTION
1370  CommonViewAllocProp( const View & view )
1371  : fad_dim ( dimension_scalar(view) )
1372  {
1374  }
1375 
1376  // TODO If assumption is insufficient, better deduction on is_view...
1377  template < class View, class ... Views >
1378  KOKKOS_INLINE_FUNCTION
1379  CommonViewAllocProp( const View & view, const Views & ... views )
1380  : fad_dim ( dimension_scalar(view, views... ) )
1381  {
1383  }
1384 };
1385 
1386 // Detect if a ViewCtorProp contains a CommonViewAllocProp
1387 template < typename ... P >
1388 struct has_common_view_alloc_prop : public std::false_type {};
1389 
1390 template < class Specialize, class ValueType >
1391 struct has_common_view_alloc_prop< CommonViewAllocProp<Specialize, ValueType> > : public std::true_type {};
1392 
1393 
1394 // Check for CommonViewAllocProp in pack of properties
1395 template < typename ... >
1396 struct check_has_common_view_alloc_prop;
1397 
1398 template <>
1399 struct check_has_common_view_alloc_prop<>
1400 {
1401  enum { value = false };
1402 };
1403 
1404 template < typename P >
1405 struct check_has_common_view_alloc_prop<P>
1406 {
1407  enum { value = has_common_view_alloc_prop< P >::value };
1408 };
1409 
1410 template < typename P0, typename ... P >
1411 struct check_has_common_view_alloc_prop<P0, P...>
1412 {
1414 };
1415 
1416 template < typename ... >
1417 struct compute_fad_dim_from_alloc_prop;
1418 
1419 template < >
1420 struct compute_fad_dim_from_alloc_prop<> {
1421  template <typename CtorProp>
1422  KOKKOS_INLINE_FUNCTION
1423  static unsigned eval(const CtorProp&) { return 0; }
1424 };
1425 
1426 template < typename P >
1427 struct compute_fad_dim_from_alloc_prop<P> {
1428  template <typename CtorProp>
1429  KOKKOS_INLINE_FUNCTION
1430  static unsigned eval(const CtorProp&) { return 0; }
1431 };
1432 
1433 template < typename P0, typename ... P >
1434 struct compute_fad_dim_from_alloc_prop<P0,P...> {
1435  template <typename CtorProp>
1436  KOKKOS_INLINE_FUNCTION
1437  static unsigned eval(const CtorProp& prop) {
1438  unsigned d1 = compute_fad_dim_from_alloc_prop<P0>::eval(prop);
1439  unsigned d2 = compute_fad_dim_from_alloc_prop<P...>::eval(prop);
1440  return d1 > d2 ? d1 : d2;
1441  }
1442 };
1443 
1444 template < class ValueType >
1445 struct compute_fad_dim_from_alloc_prop<
1446  CommonViewAllocProp<ViewSpecializeSacadoFad, ValueType>
1447  > {
1448  template <typename CtorProp>
1449  KOKKOS_INLINE_FUNCTION
1450  static unsigned eval(const CtorProp& prop) {
1451  using specialize = ViewSpecializeSacadoFad;
1452  using CVAP = CommonViewAllocProp< specialize, ValueType >;
1453  auto cast_prop = ((Kokkos::Impl::ViewCtorProp<void, CVAP> const &)prop).value;
1454  return cast_prop.fad_dim;
1455  }
1456 };
1457 
1458 template < class ValueType >
1459 struct compute_fad_dim_from_alloc_prop<
1460  CommonViewAllocProp<ViewSpecializeSacadoFadContiguous, ValueType>
1461  > {
1462  template <typename CtorProp>
1463  KOKKOS_INLINE_FUNCTION
1464  static unsigned eval(const CtorProp& prop) {
1465  using specialize = ViewSpecializeSacadoFadContiguous;
1466  using CVAP = CommonViewAllocProp< specialize, ValueType >;
1467  auto cast_prop = ((Kokkos::Impl::ViewCtorProp<void, CVAP> const &)prop).value;
1468  return cast_prop.fad_dim;
1469  }
1470 };
1471 
1472 template <typename Traits, typename ... P >
1473 struct appendFadToLayoutViewAllocHelper
1474 {
1475  using layout_type = typename Traits::array_layout;
1476  using specialize = typename Traits::specialize;
1477  using CtorProp = ViewCtorProp< P... >;
1478 
1479  KOKKOS_INLINE_FUNCTION
1480  static layout_type returnNewLayoutPlusFad( const CtorProp & arg_prop, const layout_type & arg_layout ) {
1481 
1482  layout_type appended_layout( arg_layout );
1483 
1484  // Static View case - DynRankView layout handled within createLayout calls
1485 
1486  const unsigned fad_dim =
1487  compute_fad_dim_from_alloc_prop<P...>::eval(arg_prop);
1488  appended_layout.dimension[ Traits::rank ] = (fad_dim > 0) ? fad_dim : 1;
1489 
1490  return appended_layout;
1491  }
1492 };
1493 
1494 template <typename Layout>
1495 struct prependFadToLayout
1496 {
1497  using layout_type = Layout;
1498 
1499  template < typename FadSizeType >
1500  KOKKOS_INLINE_FUNCTION
1501  static layout_type returnNewLayoutPlusFad( const layout_type & arg_layout, const FadSizeType fad_dim ) {
1502 
1503  layout_type prepended_layout(0,0,0,0,0,0,0,0);
1504 
1505  prepended_layout.dimension[0] = fad_dim;
1506 
1507  for ( int i = 1; i < ARRAY_LAYOUT_MAX_RANK; ++i ) {
1508  prepended_layout.dimension[i] = arg_layout.dimension[i-1];
1509  }
1510 
1511  return prepended_layout;
1512  }
1513 };
1514 
1515 } } // namespace Kokkos::Impl
1516 
1517 
1518 //----------------------------------------------------------------------------
1519 
1520 
1521 namespace Kokkos {
1522 namespace Impl {
1523 
1524 template< class Traits >
1525 class ViewMapping< Traits , /* View internal mapping */
1526  typename std::enable_if<
1527  ( std::is_same< typename Traits::specialize
1528  , ViewSpecializeSacadoFad >::value
1529  &&
1530  ( std::is_same< typename Traits::array_layout
1531  , Kokkos::LayoutLeft >::value
1532  ||
1533  std::is_same< typename Traits::array_layout
1534  , Kokkos::LayoutRight >::value
1535  ||
1536  std::is_same< typename Traits::array_layout
1537  , Kokkos::LayoutStride >::value
1538  )
1539  )
1540  , typename Traits::specialize
1541  >::type >
1542 {
1543 private:
1544 
1545  template< class , class ... > friend class ViewMapping ;
1546  template< class , class ... > friend class Kokkos::View ;
1547 
1548  typedef typename Traits::value_type fad_type ;
1549  typedef typename Sacado::ValueType< fad_type >::type fad_value_type ;
1550  typedef typename
1551  std::add_const< fad_value_type >::type const_fad_value_type ;
1552 
1553  enum { FadStaticDimension = Sacado::StaticSize< fad_type >::value };
1555 
1556  // Only LayoutRight has a static stride one
1557  enum { FadStaticStride =
1558  std::is_same< typename Traits::array_layout
1559  , Kokkos::LayoutRight >::value ? 1 : 0 };
1560 
1561  typedef Sacado::integral_nonzero< unsigned , FadStaticStride > sacado_stride_type;
1562 
1563  typedef fad_value_type * handle_type ;
1564 
1565  typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
1566 
1567  // Offset without Fad dimension
1568  typedef ViewOffset< typename Traits::dimension
1569  , typename Traits::array_layout
1570  , void
1571  > offset_type ;
1572 
1573  // Append the fad dimension for the internal offset mapping.
1574  typedef ViewOffset
1575  < typename array_analysis::dimension::
1576  template append<( unsigned(FadStaticDimension) > 0 ? unsigned(FadStaticDimension) + 1 : 0 )>::type
1577  , typename Traits::array_layout
1578  , void
1579  > array_offset_type ;
1580 
1581  handle_type m_impl_handle ;
1582  offset_type m_impl_offset ;
1583  array_offset_type m_array_offset ;
1584  sacado_size_type m_fad_size ;
1585  sacado_stride_type m_fad_stride ;
1586 
1587 public:
1588 
1589  //----------------------------------------
1590  // Domain dimensions
1591 
1592  enum { Rank = Traits::dimension::rank };
1593 
1594  // Using the internal offset mapping so limit to public rank:
1595  template< typename iType >
1596  KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
1597  { return m_impl_offset.m_dim.extent(r) ; }
1598 
1599  KOKKOS_INLINE_FUNCTION constexpr
1600  typename Traits::array_layout layout() const
1601  { return m_impl_offset.layout(); }
1602 
1603  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
1604  { return m_impl_offset.dimension_0(); }
1605  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
1606  { return m_impl_offset.dimension_1(); }
1607  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
1608  { return m_impl_offset.dimension_2(); }
1609  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
1610  { return m_impl_offset.dimension_3(); }
1611  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
1612  { return m_impl_offset.dimension_4(); }
1613  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
1614  { return m_impl_offset.dimension_5(); }
1615  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
1616  { return m_impl_offset.dimension_6(); }
1617  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
1618  { return m_impl_offset.dimension_7(); }
1619 
1620  // Can only be regular layout with uniform striding
1621  // when LayoutRight with contiguous values so not guaranteed true.
1622  using is_regular = std::false_type ;
1623 
1624  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const
1625  { return m_impl_offset.stride_0(); }
1626  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const
1627  { return m_impl_offset.stride_1(); }
1628  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const
1629  { return m_impl_offset.stride_2(); }
1630  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const
1631  { return m_impl_offset.stride_3(); }
1632  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const
1633  { return m_impl_offset.stride_4(); }
1634  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const
1635  { return m_impl_offset.stride_5(); }
1636  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const
1637  { return m_impl_offset.stride_6(); }
1638  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const
1639  { return m_impl_offset.stride_7(); }
1640 
1641  template< typename iType >
1642  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const
1643  { m_impl_offset.stride(s) ; }
1644 
1645  // Size of sacado scalar dimension
1646  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
1647  { return m_fad_size.value+1; }
1648 
1649  // trode of sacado scalar dimension
1650  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned stride_scalar() const
1651  { return m_fad_stride.value; }
1652 
1653  //----------------------------------------
1654  // Range of mapping
1655 
1656  // Return type of reference operators
1657  typedef typename
1659 
1661  typedef fad_value_type * pointer_type ;
1662 
1664  KOKKOS_INLINE_FUNCTION constexpr size_t span() const
1665  { return m_array_offset.span(); }
1666 
1668  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
1669  { return m_array_offset.span_is_contiguous() ; }
1670 
1672  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
1673  { return m_impl_handle ; }
1674 
1675  //----------------------------------------
1676 
1677  KOKKOS_FORCEINLINE_FUNCTION
1678  reference_type reference() const
1679  { return reference_type( m_impl_handle
1680  , m_fad_size.value
1681  , m_fad_stride.value ); }
1682 
1683  template< typename I0 >
1684  KOKKOS_FORCEINLINE_FUNCTION
1685  reference_type
1686  reference( const I0 & i0 ) const
1687  { return reference_type( m_impl_handle + m_array_offset(i0,0)
1688  , m_fad_size.value
1689  , m_fad_stride.value ); }
1690 
1691  template< typename I0 , typename I1 >
1692  KOKKOS_FORCEINLINE_FUNCTION
1693  reference_type reference( const I0 & i0 , const I1 & i1 ) const
1694  { return reference_type( m_impl_handle + m_array_offset(i0,i1,0)
1695  , m_fad_size.value
1696  , m_fad_stride.value ); }
1697 
1698 
1699  template< typename I0 , typename I1 , typename I2 >
1700  KOKKOS_FORCEINLINE_FUNCTION
1701  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
1702  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,0)
1703  , m_fad_size.value
1704  , m_fad_stride.value ); }
1705 
1706  template< typename I0 , typename I1 , typename I2 , typename I3 >
1707  KOKKOS_FORCEINLINE_FUNCTION
1708  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
1709  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,0)
1710  , m_fad_size.value
1711  , m_fad_stride.value ); }
1712 
1713  template< typename I0 , typename I1 , typename I2 , typename I3
1714  , typename I4 >
1715  KOKKOS_FORCEINLINE_FUNCTION
1716  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1717  , const I4 & i4 ) const
1718  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,0)
1719  , m_fad_size.value
1720  , m_fad_stride.value ); }
1721 
1722  template< typename I0 , typename I1 , typename I2 , typename I3
1723  , typename I4 , typename I5 >
1724  KOKKOS_FORCEINLINE_FUNCTION
1725  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1726  , const I4 & i4 , const I5 & i5 ) const
1727  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,i5,0)
1728  , m_fad_size.value
1729  , m_fad_stride.value ); }
1730 
1731 
1732  template< typename I0 , typename I1 , typename I2 , typename I3
1733  , typename I4 , typename I5 , typename I6 >
1734  KOKKOS_FORCEINLINE_FUNCTION
1735  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1736  , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
1737  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,i5,i6,0)
1738  , m_fad_size.value
1739  , m_fad_stride.value ); }
1740 
1741  //----------------------------------------
1742 
1744  KOKKOS_INLINE_FUNCTION
1745  static size_t memory_span( typename Traits::array_layout const & layout )
1746  {
1747  size_t dims[8];
1748  for (int i=0; i<8; ++i)
1749  dims[i] = layout.dimension[i];
1750  if (unsigned(FadStaticDimension) > 0)
1751  dims[unsigned(Rank)] = FadStaticDimension+1;
1752 
1753  typename Traits::array_layout alayout(
1754  dims[0], dims[1], dims[2], dims[3],
1755  dims[4], dims[5], dims[6], dims[7] );
1756 
1757  // Do not introduce padding...
1758  typedef std::integral_constant< unsigned , 0 > padding ;
1759  return array_offset_type( padding() , alayout ).span() * sizeof(fad_value_type);
1760  }
1761 
1762  //----------------------------------------
1763 
1764  KOKKOS_INLINE_FUNCTION ~ViewMapping() {}
1765  KOKKOS_INLINE_FUNCTION ViewMapping() : m_impl_handle(0) , m_impl_offset() , m_array_offset() , m_fad_size(0) , m_fad_stride(0) {}
1766 
1767  KOKKOS_DEFAULTED_FUNCTION ViewMapping( const ViewMapping & ) = default ;
1768  KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
1769 
1770  KOKKOS_DEFAULTED_FUNCTION ViewMapping( ViewMapping && ) = default ;
1771  KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
1772 
1773  template< class ... P >
1774  KOKKOS_INLINE_FUNCTION
1775  ViewMapping
1776  ( ViewCtorProp< P ... > const & prop
1777  , typename Traits::array_layout const & local_layout
1778  )
1779  : m_impl_handle( ( (ViewCtorProp<void,pointer_type> const &) prop ).value )
1780  , m_impl_offset( std::integral_constant< unsigned , 0 >()
1781  , local_layout )
1782  , m_array_offset( std::integral_constant< unsigned , 0 >()
1783  , local_layout )
1784  // Query m_array_offset, not input, in case of static dimension
1785  , m_fad_size(
1786  ( Rank == 0 ? m_array_offset.dimension_0() :
1787  ( Rank == 1 ? m_array_offset.dimension_1() :
1788  ( Rank == 2 ? m_array_offset.dimension_2() :
1789  ( Rank == 3 ? m_array_offset.dimension_3() :
1790  ( Rank == 4 ? m_array_offset.dimension_4() :
1791  ( Rank == 5 ? m_array_offset.dimension_5() :
1792  ( Rank == 6 ? m_array_offset.dimension_6() :
1793  m_array_offset.dimension_7() ))))))) - 1 )
1794  , m_fad_stride(
1795  ( Rank == 0 ? m_array_offset.stride_0() :
1796  ( Rank == 1 ? m_array_offset.stride_1() :
1797  ( Rank == 2 ? m_array_offset.stride_2() :
1798  ( Rank == 3 ? m_array_offset.stride_3() :
1799  ( Rank == 4 ? m_array_offset.stride_4() :
1800  ( Rank == 5 ? m_array_offset.stride_5() :
1801  ( Rank == 6 ? m_array_offset.stride_6() :
1802  m_array_offset.stride_7() ))))))))
1803 
1804  {
1805  const unsigned fad_dim =
1806  ( Rank == 0 ? m_array_offset.dimension_0() :
1807  ( Rank == 1 ? m_array_offset.dimension_1() :
1808  ( Rank == 2 ? m_array_offset.dimension_2() :
1809  ( Rank == 3 ? m_array_offset.dimension_3() :
1810  ( Rank == 4 ? m_array_offset.dimension_4() :
1811  ( Rank == 5 ? m_array_offset.dimension_5() :
1812  ( Rank == 6 ? m_array_offset.dimension_6() :
1813  m_array_offset.dimension_7() )))))));
1814  if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
1815  Kokkos::abort("invalid fad dimension (0) supplied!");
1816  }
1817 
1818  //----------------------------------------
1819  /* Allocate and construct mapped array.
1820  * Allocate via shared allocation record and
1821  * return that record for allocation tracking.
1822  */
1823  template< class ... P >
1824  SharedAllocationRecord<> *
1825  allocate_shared( ViewCtorProp< P... > const & prop
1826  , typename Traits::array_layout const & local_layout
1827  , bool execution_space_specified)
1828  {
1829  typedef ViewCtorProp< P... > ctor_prop ;
1830 
1831  typedef typename ctor_prop::execution_space execution_space ;
1832  typedef typename Traits::memory_space memory_space ;
1833  typedef ViewValueFunctor< execution_space , fad_value_type > functor_type ;
1834  typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
1835 
1836  // Disallow padding
1837  typedef std::integral_constant< unsigned , 0 > padding ;
1838 
1839  // Check if ViewCtorProp has CommonViewAllocProp - if so, retrieve the fad_size and append to layout
1840  enum { test_traits_check = Kokkos::Impl::check_has_common_view_alloc_prop< P... >::value };
1841 
1842  m_impl_offset = offset_type( padding(), local_layout );
1843 
1844  typename Traits::array_layout internal_layout =
1845  (test_traits_check == true)
1846  ? Kokkos::Impl::appendFadToLayoutViewAllocHelper< Traits, P... >::returnNewLayoutPlusFad(prop, local_layout)
1847  : local_layout;
1848 
1849  m_array_offset = array_offset_type( padding(), internal_layout );
1850 
1851  const unsigned fad_dim =
1852  ( Rank == 0 ? m_array_offset.dimension_0() :
1853  ( Rank == 1 ? m_array_offset.dimension_1() :
1854  ( Rank == 2 ? m_array_offset.dimension_2() :
1855  ( Rank == 3 ? m_array_offset.dimension_3() :
1856  ( Rank == 4 ? m_array_offset.dimension_4() :
1857  ( Rank == 5 ? m_array_offset.dimension_5() :
1858  ( Rank == 6 ? m_array_offset.dimension_6() :
1859  m_array_offset.dimension_7() )))))));
1860  if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
1861  Kokkos::abort("invalid fad dimension (0) supplied!");
1862  m_fad_size = fad_dim - 1 ;
1863 
1864  m_fad_stride =
1865  ( Rank == 0 ? m_array_offset.stride_0() :
1866  ( Rank == 1 ? m_array_offset.stride_1() :
1867  ( Rank == 2 ? m_array_offset.stride_2() :
1868  ( Rank == 3 ? m_array_offset.stride_3() :
1869  ( Rank == 4 ? m_array_offset.stride_4() :
1870  ( Rank == 5 ? m_array_offset.stride_5() :
1871  ( Rank == 6 ? m_array_offset.stride_6() :
1872  m_array_offset.stride_7() )))))));
1873 
1874  const size_t alloc_size = m_array_offset.span() * sizeof(fad_value_type);
1875 
1876  // Create shared memory tracking record with allocate memory from the memory space
1877  record_type * const record =
1878  record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
1879  , ( (ViewCtorProp<void,std::string> const &) prop ).value
1880  , alloc_size );
1881 
1882  // Only set the the pointer and initialize if the allocation is non-zero.
1883  // May be zero if one of the dimensions is zero.
1884  if ( alloc_size ) {
1885 
1886  m_impl_handle = handle_type( reinterpret_cast< pointer_type >( record->data() ) );
1887 
1888  if ( ctor_prop::initialize ) {
1889  auto space = ((ViewCtorProp<void,execution_space> const &) prop).value;
1890  // Assume destruction is only required when construction is requested.
1891  // The ViewValueFunctor has both value construction and destruction operators.
1892  if (execution_space_specified)
1893  record->m_destroy = functor_type( space
1894  , (fad_value_type *) m_impl_handle
1895  , m_array_offset.span()
1896  , record->get_label()
1897  );
1898  else
1899  record->m_destroy = functor_type((fad_value_type *) m_impl_handle
1900  , m_array_offset.span()
1901  , record->get_label()
1902  );
1903 
1904  // Construct values
1905  record->m_destroy.construct_shared_allocation();
1906  space.fence();
1907  }
1908  }
1909 
1910  return record ;
1911  }
1912 
1913 };
1914 
1915 } // namespace Impl
1916 } // namespace Kokkos
1917 
1918 //----------------------------------------------------------------------------
1919 
1920 namespace Kokkos {
1921 namespace Impl {
1922 
1927 template< class DstTraits , class SrcTraits >
1928 class ViewMapping< DstTraits , SrcTraits ,
1929  typename std::enable_if<(
1930  Kokkos::Impl::MemorySpaceAccess
1931  < typename DstTraits::memory_space
1932  , typename SrcTraits::memory_space >::assignable
1933  &&
1934  // Destination view has FAD
1935  std::is_same< typename DstTraits::specialize
1936  , ViewSpecializeSacadoFad >::value
1937  &&
1938  // Source view has FAD
1939  std::is_same< typename SrcTraits::specialize
1940  , ViewSpecializeSacadoFad >::value
1941 
1942  )
1943  , typename DstTraits::specialize
1944  >::type >
1945 {
1946 public:
1947 
1948  enum { is_assignable = true };
1949  enum { is_assignable_data_type = true };
1950 
1951  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1952  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1953  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1954 
1955  template< class DstType >
1956  KOKKOS_INLINE_FUNCTION static
1957  void assign( DstType & dst
1958  , const SrcFadType & src
1959  , const TrackType & )
1960  {
1961  static_assert(
1962  (
1963  std::is_same< typename DstTraits::array_layout
1964  , Kokkos::LayoutLeft >::value ||
1965  std::is_same< typename DstTraits::array_layout
1966  , Kokkos::LayoutRight >::value ||
1967  std::is_same< typename DstTraits::array_layout
1968  , Kokkos::LayoutStride >::value
1969  )
1970  &&
1971  (
1972  std::is_same< typename SrcTraits::array_layout
1973  , Kokkos::LayoutLeft >::value ||
1974  std::is_same< typename SrcTraits::array_layout
1975  , Kokkos::LayoutRight >::value ||
1976  std::is_same< typename SrcTraits::array_layout
1977  , Kokkos::LayoutStride >::value
1978  )
1979  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1980 
1981  static_assert(
1982  std::is_same< typename DstTraits::array_layout
1983  , typename SrcTraits::array_layout >::value ||
1984  std::is_same< typename DstTraits::array_layout
1985  , Kokkos::LayoutStride >::value ,
1986  "View assignment must have compatible layout" );
1987 
1988  static_assert(
1989  std::is_same< typename DstTraits::value_type
1990  , typename SrcTraits::value_type >::value ||
1991  std::is_same< typename DstTraits::value_type
1992  , typename SrcTraits::const_value_type >::value ,
1993  "View assignment must have same value type or const = non-const" );
1994 
1995  static_assert(
1996  ViewDimensionAssignable
1997  < typename DstType::offset_type::dimension_type
1998  , typename SrcFadType::offset_type::dimension_type >::value ,
1999  "View assignment must have compatible dimensions" );
2000 
2001  static_assert(
2002  ViewDimensionAssignable
2003  < typename DstType::array_offset_type::dimension_type
2004  , typename SrcFadType::array_offset_type::dimension_type >::value ,
2005  "View assignment must have compatible dimensions" );
2006 
2007  typedef typename DstType::offset_type dst_offset_type ;
2008  typedef typename DstType::array_offset_type dst_array_offset_type ;
2009 
2010  dst.m_impl_handle = src.m_impl_handle ;
2011  dst.m_impl_offset = dst_offset_type( src.m_impl_offset );
2012  dst.m_array_offset = dst_array_offset_type( src.m_array_offset );
2013  dst.m_fad_size = src.m_fad_size.value ;
2014  dst.m_fad_stride = src.m_fad_stride.value ;
2015  }
2016 };
2017 
2018 // Integer argument is the actual rank => ranks 0 to Rank-1 will be assigned
2024 template< class DstTraits , class SrcTraits >
2025 class ViewMapping< DstTraits , SrcTraits ,
2026  typename std::enable_if<(
2027  Kokkos::Impl::MemorySpaceAccess
2028  < typename DstTraits::memory_space
2029  , typename SrcTraits::memory_space >::assignable
2030  &&
2031  // Destination view has ordinary
2032  std::is_same< typename DstTraits::specialize , void >::value
2033  &&
2034  // Source view has FAD only
2035  std::is_same< typename SrcTraits::specialize
2036  , ViewSpecializeSacadoFad >::value
2037  )
2038  , typename DstTraits::specialize
2039  >::type >
2040 {
2041 public:
2042 
2043  enum { is_assignable = true };
2044  enum { is_assignable_data_type = true };
2045 
2046 
2047  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
2048  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
2049  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
2050 
2051 
2052  // Helpers to assign, and generate if necessary, ViewOffset to the dst map
2053  // These are necessary to use Kokkos' deep_copy with nested fads
2054  template < class DstType, class SrcFadType, class Truth = void >
2055  struct AssignOffset;
2056 
2057  template < class DstType, class SrcFadType >
2058  struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank != (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
2059  {
2060  // ViewOffset's Dimensions Ranks do not match
2061  KOKKOS_INLINE_FUNCTION
2062  static void assign( DstType & dst, const SrcFadType & src )
2063  {
2064  typedef typename SrcTraits::value_type TraitsValueType;
2065 
2068  )
2069  {
2070  typedef typename DstType::offset_type::array_layout DstLayoutType;
2071  //typedef typename ViewArrayLayoutSelector<typename DstType::offset_type::array_layout>::type DstLayoutType;
2072  typedef typename SrcFadType::array_offset_type::dimension_type SrcViewDimension;
2073 
2074  // This is the static dimension of the inner fad, missing from ViewDimension
2076 
2077  static constexpr bool is_layout_left =
2079 
2080  typedef typename std::conditional< is_layout_left,
2081  typename SrcViewDimension:: template prepend< InnerStaticDim+1 >::type,
2082  typename SrcViewDimension:: template append < InnerStaticDim+1 >::type
2083  >::type SrcViewDimensionAppended;
2084 
2085  typedef std::integral_constant< unsigned , 0 > padding ;
2086 
2087  typedef ViewOffset< SrcViewDimensionAppended, DstLayoutType > TmpOffsetType;
2088 
2089  auto src_layout = src.m_array_offset.layout();
2090 
2091  if ( is_layout_left ) {
2092  auto prepend_layout = Kokkos::Impl::prependFadToLayout< DstLayoutType >::returnNewLayoutPlusFad(src_layout, InnerStaticDim+1);
2093  TmpOffsetType offset_tmp( padding(), prepend_layout );
2094  dst.m_impl_offset = offset_tmp;
2095  }
2096  else {
2097  TmpOffsetType offset_tmp( padding(), src_layout );
2098  dst.m_impl_offset = offset_tmp;
2099  }
2100 
2101  } else {
2102  Kokkos::abort("Sacado error: Applying AssignOffset for case with nested Fads, but without nested Fads - something went wrong");
2103  }
2104  }
2105  };
2106 
2107  template < class DstType, class SrcFadType >
2108  struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank == (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
2109  {
2110  KOKKOS_INLINE_FUNCTION
2111  static void assign( DstType & dst, const SrcFadType & src )
2112  {
2113 
2114  typedef typename DstType::offset_type dst_offset_type ;
2115  dst.m_impl_offset = dst_offset_type( src.m_array_offset );
2116  }
2117  };
2118 
2119 
2120 // If the dst and src mappings are not equal in Rank, the src should come from a View of nested fads
2121 // In the case of two nested fads, the innermost must be an SFad (static Fad)
2122 // The offset_type's are not compatible in the case of nested fads because the ViewDimension's ranks will not agree
2123 // In this case, rather than trying to construct an offset_type from src (which will fail at compile time)
2124 // and assign to dst.m_impl_offset, manually assign the ViewDimension arguments to dst;
2125 // requires appending the missing inner SFad dim + 1 to the Rank-1 ViewDimension
2126  // DstType and SrcFadType are MAPS...
2127  template < class DstType >
2128  KOKKOS_INLINE_FUNCTION static
2129  void
2130  assign( DstType & dst
2131  , const SrcFadType & src
2132  , const TrackType &
2133  )
2134  {
2135 
2136  static_assert(
2137  (
2138  std::is_same< typename DstTraits::array_layout
2139  , Kokkos::LayoutLeft >::value ||
2140  std::is_same< typename DstTraits::array_layout
2141  , Kokkos::LayoutRight >::value ||
2142  std::is_same< typename DstTraits::array_layout
2143  , Kokkos::LayoutStride >::value
2144  )
2145  &&
2146  (
2147  std::is_same< typename SrcTraits::array_layout
2148  , Kokkos::LayoutLeft >::value ||
2149  std::is_same< typename SrcTraits::array_layout
2150  , Kokkos::LayoutRight >::value ||
2151  std::is_same< typename SrcTraits::array_layout
2152  , Kokkos::LayoutStride >::value
2153  )
2154  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
2155 
2156  static_assert(
2157  std::is_same< typename DstTraits::array_layout
2158  , typename SrcTraits::array_layout >::value ||
2159  std::is_same< typename DstTraits::array_layout
2160  , Kokkos::LayoutStride >::value ,
2161  "View assignment must have compatible layout" );
2162 #if 0
2163  static_assert(
2164  std::is_same< typename DstTraits::scalar_array_type
2165  , typename SrcTraits::scalar_array_type >::value ||
2166  std::is_same< typename DstTraits::scalar_array_type
2167  , typename SrcTraits::const_scalar_array_type >::value ,
2168  "View assignment must have same value type or const = non-const" );
2169 #endif
2170 
2171  AssignOffset< DstType, SrcFadType >::assign( dst, src );
2172 
2173  dst.m_impl_handle = reinterpret_cast< typename DstType::handle_type >(src.m_impl_handle) ;
2174  }
2175 };
2176 
2177 } // namespace Impl
2178 } // namespace Kokkos
2179 
2180 //----------------------------------------------------------------------------
2181 
2182 namespace Kokkos {
2183 namespace Impl {
2184 
2185 // Subview mapping
2186 
2187 template< class SrcTraits , class ... Args >
2188 struct ViewMapping
2189  < typename std::enable_if<(
2190  // Source view has FAD only
2191  std::is_same< typename SrcTraits::specialize
2192  , ViewSpecializeSacadoFad >::value
2193  &&
2194  (
2195  std::is_same< typename SrcTraits::array_layout
2196  , Kokkos::LayoutLeft >::value ||
2197  std::is_same< typename SrcTraits::array_layout
2198  , Kokkos::LayoutRight >::value ||
2199  std::is_same< typename SrcTraits::array_layout
2200  , Kokkos::LayoutStride >::value
2201  )
2202  )
2203  >::type
2204  , SrcTraits
2205  , Args ... >
2206 {
2207 private:
2208 
2209  static_assert( SrcTraits::rank == sizeof...(Args) , "" );
2210 
2211  enum
2212  { RZ = false
2220  };
2221 
2222  // Public rank
2223  enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
2224  + unsigned(R4) + unsigned(R5) + unsigned(R6) };
2225 
2226  // Whether right-most non-FAD rank is a range.
2227  enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
2228  1 == SrcTraits::rank ? R0 : (
2229  2 == SrcTraits::rank ? R1 : (
2230  3 == SrcTraits::rank ? R2 : (
2231  4 == SrcTraits::rank ? R3 : (
2232  5 == SrcTraits::rank ? R4 : (
2233  6 == SrcTraits::rank ? R5 : R6 ))))))) };
2234 
2235  // Subview's layout
2236  // If LayoutRight then FAD is contiguous
2237  // For LayoutLeft, result is LayoutLeft only if 1st arg is a range,
2238  // and since last (FAD) dimension is also a range, and these
2239  // ranges must be consecutive, the input rank must be 1
2240  typedef typename std::conditional<
2241  ( /* Same layout IF */
2242  ( rank == 0 )
2243  ||
2244  ( std::is_same< typename SrcTraits::array_layout
2245  , Kokkos::LayoutRight >::value
2246  &&
2247  ( rank == 1 ) && R0_rev
2248  )
2249  ||
2250  ( std::is_same< typename SrcTraits::array_layout
2251  , Kokkos::LayoutLeft >::value
2252  &&
2253  ( rank == 1 ) && (SrcTraits::rank == 1) && R0
2254  )
2255  ), typename SrcTraits::array_layout , Kokkos::LayoutStride
2256  >::type array_layout ;
2257 
2258  typedef typename SrcTraits::value_type fad_type ;
2259 
2260  typedef typename std::conditional< rank == 0 , fad_type ,
2261  typename std::conditional< rank == 1 , fad_type * ,
2262  typename std::conditional< rank == 2 , fad_type ** ,
2263  typename std::conditional< rank == 3 , fad_type *** ,
2264  typename std::conditional< rank == 4 , fad_type **** ,
2265  typename std::conditional< rank == 5 , fad_type ***** ,
2266  typename std::conditional< rank == 6 , fad_type ****** ,
2267  fad_type *******
2268  >::type >::type >::type >::type >::type >::type >::type
2269  data_type ;
2270 
2271 public:
2272 
2273  typedef Kokkos::ViewTraits
2274  < data_type
2275  , array_layout
2276  , typename SrcTraits::device_type
2277  , typename SrcTraits::memory_traits > traits_type ;
2278 
2279  typedef Kokkos::View
2280  < data_type
2281  , array_layout
2282  , typename SrcTraits::device_type
2283  , typename SrcTraits::memory_traits > type ;
2284 
2285 
2286  KOKKOS_INLINE_FUNCTION
2287  static void assign( ViewMapping< traits_type , typename traits_type::specialize > & dst
2288  , ViewMapping< SrcTraits ,typename SrcTraits::specialize > const & src
2289  , Args ... args )
2290  {
2291  typedef ViewMapping< traits_type , typename traits_type::specialize > DstType ;
2292  typedef typename DstType::offset_type dst_offset_type ;
2293  typedef typename DstType::array_offset_type dst_array_offset_type ;
2294  typedef typename DstType::handle_type dst_handle_type ;
2295 
2296  const SubviewExtents< SrcTraits::rank , rank >
2297  extents( src.m_impl_offset.m_dim , args... );
2298  const SubviewExtents< SrcTraits::rank + 1 , rank + 1 >
2299  array_extents( src.m_array_offset.m_dim , args... , Kokkos::ALL() );
2300 
2301  dst.m_impl_offset = dst_offset_type( src.m_impl_offset , extents );
2302  dst.m_array_offset = dst_array_offset_type( src.m_array_offset , array_extents );
2303  dst.m_impl_handle =
2304  dst_handle_type( src.m_impl_handle +
2305  src.m_array_offset( array_extents.domain_offset(0)
2306  , array_extents.domain_offset(1)
2307  , array_extents.domain_offset(2)
2308  , array_extents.domain_offset(3)
2309  , array_extents.domain_offset(4)
2310  , array_extents.domain_offset(5)
2311  , array_extents.domain_offset(6)
2312  , array_extents.domain_offset(7) ) );
2313  dst.m_fad_size = src.m_fad_size;
2314  dst.m_fad_stride = src.m_fad_stride.value;
2315  }
2316 
2317 };
2318 
2319 } // namespace Impl
2320 } // namespace Kokkos
2321 
2322 //----------------------------------------------------------------------------
2323 //----------------------------------------------------------------------------
2324 
2325 #if defined(HAVE_SACADO_KOKKOS) && \
2326  defined(HAVE_SACADO_TEUCHOSKOKKOSCOMM) && \
2327  defined(HAVE_SACADO_VIEW_SPEC) && \
2328  ! defined(SACADO_DISABLE_FAD_VIEW_SPEC)
2329 
2330 #include "Kokkos_TeuchosCommAdapters.hpp"
2331 
2332 namespace Teuchos {
2333 
2334 template< typename Ordinal , class SD , class ... SP , class RD , class ... RP >
2335 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
2336  Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
2337  >::type
2338 reduceAll
2339  ( const Comm<Ordinal>& comm,
2340  const EReductionType reductType ,
2341  const Ordinal count,
2342  const Kokkos::View<SD,SP...> & sendBuffer ,
2343  const Kokkos::View<RD,RP...> & recvBuffer )
2344 {
2345  // We can't implement reduceAll by extracting the underlying array (since we
2346  // can't reduce across the derivative dimension) and we can't just extract
2347  // a pointer due to ViewFad. In principle we could handle ViewFad in the
2348  // serializer, but for the time being we just copy the view's into local
2349  // buffers (on the host).
2350  typedef Kokkos::View<SD,SP...> SendViewType;
2351  typedef Kokkos::View<RD,RP...> RecvViewType;
2352  typedef typename SendViewType::value_type send_value_type;
2353  typedef typename RecvViewType::value_type recv_value_type;
2354 
2356  SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
2357  "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
2358  "The send View's rank is " << SendViewType::rank << " and the receive "
2359  "View's rank is " << RecvViewType::rank << ".");
2360 
2361  // Copy send buffer into local array
2362  Teuchos::Array<send_value_type> localSendBuffer(count);
2363  typename SendViewType::host_mirror_type hostSendBuffer =
2364  Kokkos::create_mirror_view(sendBuffer);
2365  Kokkos::deep_copy(hostSendBuffer, sendBuffer);
2366  for (Ordinal i=0; i<count; ++i)
2367  localSendBuffer[i] = hostSendBuffer(i);
2368 
2369  // Copy receive buffer into local array (necessary to initialize Fad types
2370  // properly)
2371  Teuchos::Array<recv_value_type> localRecvBuffer(count);
2372  typename RecvViewType::host_mirror_type hostRecvBuffer =
2373  Kokkos::create_mirror_view(recvBuffer);
2374  Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
2375  for (Ordinal i=0; i<count; ++i)
2376  localRecvBuffer[i] = hostRecvBuffer(i);
2377 
2378  // Do reduce-all
2379  reduceAll(comm, reductType, count,
2380  localSendBuffer.getRawPtr(),
2381  localRecvBuffer.getRawPtr());
2382 
2383  // Copy back into original buffer
2384  for (Ordinal i=0; i<count; ++i)
2385  hostRecvBuffer(i) = localRecvBuffer[i];
2386  Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
2387 }
2388 
2389 
2390 template< typename Ordinal , typename Serializer ,
2391  class SD , class ... SP , class RD , class ... RP >
2392 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
2393  Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
2394  >::type
2395 reduceAll
2396  ( const Comm<Ordinal>& comm,
2397  const Serializer& serializer,
2398  const EReductionType reductType ,
2399  const Ordinal count,
2400  const Kokkos::View<SD,SP...> & sendBuffer ,
2401  const Kokkos::View<RD,RP...> & recvBuffer )
2402 {
2403  // We can't implement reduceAll by extracting the underlying array (since we
2404  // can't reduce across the derivative dimension) and we can't just extract
2405  // a pointer due to ViewFad. In principle we could handle ViewFad in the
2406  // serializer, but for the time being we just copy the view's into local
2407  // buffers (on the host).
2408  typedef Kokkos::View<SD,SP...> SendViewType;
2409  typedef Kokkos::View<RD,RP...> RecvViewType;
2410  typedef typename SendViewType::value_type send_value_type;
2411  typedef typename RecvViewType::value_type recv_value_type;
2412 
2414  SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
2415  "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
2416  "The send View's rank is " << SendViewType::rank << " and the receive " "View's rank is " << RecvViewType::rank << ".");
2417 
2418  // Copy send buffer into local array
2419  Teuchos::Array<send_value_type> localSendBuffer(count);
2420  typename SendViewType::host_mirror_type hostSendBuffer =
2421  Kokkos::create_mirror_view(sendBuffer);
2422  Kokkos::deep_copy(hostSendBuffer, sendBuffer);
2423  for (Ordinal i=0; i<count; ++i)
2424  localSendBuffer[i] = hostSendBuffer(i);
2425 
2426  // Copy receive buffer into local array (necessary to initialize Fad types
2427  // properly)
2428  Teuchos::Array<recv_value_type> localRecvBuffer(count);
2429  typename RecvViewType::host_mirror_type hostRecvBuffer =
2430  Kokkos::create_mirror_view(recvBuffer);
2431  Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
2432  for (Ordinal i=0; i<count; ++i)
2433  localRecvBuffer[i] = hostRecvBuffer(i);
2434 
2435  // Do reduce-all
2436  reduceAll(comm, serializer, reductType, count,
2437  localSendBuffer.getRawPtr(),
2438  localRecvBuffer.getRawPtr());
2439 
2440  // Copy back into original buffer
2441  for (Ordinal i=0; i<count; ++i)
2442  hostRecvBuffer(i) = localRecvBuffer[i];
2443  Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
2444 }
2445 
2446 
2447 template<typename Ordinal, class D, class ... P >
2448 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
2449 broadcast
2450  ( const Comm<Ordinal>& comm,
2451  const int rootRank ,
2452  const Ordinal count,
2453  const Kokkos::View<D,P...>& buffer)
2454 {
2455  typedef Kokkos::View<D,P...> view_type;
2456  typename view_type::array_type array_buffer = buffer;
2457  Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
2458  broadcast( comm, rootRank, array_count, array_buffer );
2459 }
2460 
2461 template<typename Ordinal,
2462  typename Serializer ,
2463  class D, class ... P >
2464 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
2465 broadcast
2466  ( const Comm<Ordinal>& comm,
2467  const Serializer& serializer,
2468  const int rootRank ,
2469  const Ordinal count,
2470  const Kokkos::View<D,P...>& buffer)
2471 {
2472  typedef Kokkos::View<D,P...> view_type;
2473  typename view_type::array_type array_buffer = buffer;
2474  Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
2475  broadcast( comm, *(serializer.getValueSerializer()), rootRank,
2476  array_count, array_buffer );
2477 }
2478 
2479 } // namespace Teuchos
2480 
2481 #endif
2482 
2483 //----------------------------------------------------------------------------
2484 
2485 #endif // defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
2486 
2487 #endif // defined(HAVE_SACADO_KOKKOS)
2488 
2490 
2491 #endif // defined(SACADO_HAS_NEW_KOKKOS_VIEW_IMPL)
2492 #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP */
int * count
Base template specification for ScalarType.
Base template specification for whether a type is a Fad type.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
GeneralFad< StaticStorage< T, Num > > SLFad
Base template specification for static size.
#define T
Definition: Sacado_rad.hpp:553
#define D
Definition: Sacado_rad.hpp:557
GeneralFad< DynamicStorage< T > > DFad
int value
const int N
int Ordinal
void
Definition: uninit.c:105
const int fad_dim
expr expr expr bar false
GeneralFad< StaticFixedStorage< T, Num > > SFad
Base template specification for Promote.
if(first)
Definition: uninit.c:110
Base template specification for testing whether type is statically sized.
Get view type for any Fad type.