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