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