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