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>
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>
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>
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 
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  execution_space().fence();
370  }
371 };
372 
373 }
374 
375 // Overload of deep_copy for Fad views intializing to a constant scalar
376 template< class DT, class ... DP >
377 void deep_copy(
378  const View<DT,DP...> & view ,
379  const typename Sacado::ScalarType< typename View<DT,DP...>::value_type >::type & value
380  , typename std::enable_if<(
381  std::is_same< typename ViewTraits<DT,DP...>::specialize
382  , Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
383  std::is_same< typename ViewTraits<DT,DP...>::specialize
384  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value
385  )>::type * = 0 )
386 {
387  static_assert(
388  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
389  typename ViewTraits<DT,DP...>::non_const_value_type >::value
390  , "Can only deep copy into non-const type" );
391 
392  Impl::SacadoViewFill< View<DT,DP...> >( view , value );
393 }
394 
395 
396 // Overload of deep_copy for Fad views intializing to a constant Fad
397 template< class DT, class ... DP >
398 void deep_copy(
399  const View<DT,DP...> & view ,
400  const typename View<DT,DP...>::value_type & value
401  , typename std::enable_if<(
402  std::is_same< typename ViewTraits<DT,DP...>::specialize
403  , Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
404  std::is_same< typename ViewTraits<DT,DP...>::specialize
405  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value
406  )>::type * = 0 )
407 {
408  static_assert(
409  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
410  typename ViewTraits<DT,DP...>::non_const_value_type >::value
411  , "Can only deep copy into non-const type" );
412 
413  Impl::SacadoViewFill< View<DT,DP...> >( view , value );
414 }
415 
416 
417 /* Specialize for deep copy of FAD */
418 template< class DT , class ... DP , class ST , class ... SP >
419 inline
420 void deep_copy( const View<DT,DP...> & dst ,
421  const View<ST,SP...> & src
422  , typename std::enable_if<(
423  ( std::is_same< typename ViewTraits<DT,DP...>::specialize
424  , Kokkos::Impl::ViewSpecializeSacadoFad >::value
425  ||
426  std::is_same< typename ViewTraits<DT,DP...>::specialize
427  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
428  &&
429  ( std::is_same< typename ViewTraits<ST,SP...>::specialize
430  , Kokkos::Impl::ViewSpecializeSacadoFad >::value
431  ||
432  std::is_same< typename ViewTraits<ST,SP...>::specialize
433  , Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
434  )>::type * = 0 )
435 {
436  static_assert(
437  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
438  typename ViewTraits<DT,DP...>::non_const_value_type >::value
439  , "Deep copy destination must be non-const" );
440 
441  static_assert(
442  ( unsigned(ViewTraits<DT,DP...>::rank) ==
443  unsigned(ViewTraits<ST,SP...>::rank) )
444  , "Deep copy destination and source must have same rank" );
445 
446 #if 0
447  // Current impl
448  typedef typename View<DT,DP...>::array_type dst_array_type;
449  typedef typename View<ST,SP...>::array_type src_array_type;
450  typename NaturalArrayType< dst_array_type >::type dst_array( dst );
451  typename NaturalArrayType< src_array_type >::type src_array( src );
452 #else
453  // Copy-assign Views of FadType to Kokkos Views to use Kokkos' deep_copy routine
454  typename PODViewDeepCopyType< View<DT,DP...> >::type dst_array( dst );
455  typename PODViewDeepCopyType< View<ST,SP...> >::type src_array( src );
456 #endif
457  Kokkos::deep_copy( dst_array , src_array );
458 }
459 
460 template< class T , class ... P >
461 inline
462 typename Kokkos::View<T,P...>::HostMirror
463 create_mirror( const Kokkos::View<T,P...> & src
464  , typename std::enable_if<
465  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
466  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
467  std::is_same< typename ViewTraits<T,P...>::specialize ,
468  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
469  &&
470  ! std::is_same< typename Kokkos::ViewTraits<T,P...>::array_layout
471  , Kokkos::LayoutStride >::value
472  >::type *
473  )
474 {
475  typedef View<T,P...> src_type ;
476  typedef typename src_type::HostMirror dst_type ;
477 
478  typename src_type::array_layout layout = src.layout();
479  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
480 
481  return dst_type(std::string(src.label()).append("_mirror"), layout);
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  Kokkos::LayoutStride layout ;
503 
504  layout.dimension[0] = src.extent(0);
505  layout.dimension[1] = src.extent(1);
506  layout.dimension[2] = src.extent(2);
507  layout.dimension[3] = src.extent(3);
508  layout.dimension[4] = src.extent(4);
509  layout.dimension[5] = src.extent(5);
510  layout.dimension[6] = src.extent(6);
511  layout.dimension[7] = src.extent(7);
512 
513  layout.stride[0] = src.stride_0();
514  layout.stride[1] = src.stride_1();
515  layout.stride[2] = src.stride_2();
516  layout.stride[3] = src.stride_3();
517  layout.stride[4] = src.stride_4();
518  layout.stride[5] = src.stride_5();
519  layout.stride[6] = src.stride_6();
520  layout.stride[7] = src.stride_7();
521 
522  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
523 
524  return dst_type(std::string(src.label()).append("_mirror"), layout);
525 }
526 
527 template<class Space, class T, class ... P>
528 typename Impl::MirrorType<Space,T,P ...>::view_type
529 create_mirror(const Space& , const Kokkos::View<T,P...> & src
530  , typename std::enable_if<
531  ( std::is_same< typename ViewTraits<T,P...>::specialize ,
532  Kokkos::Impl::ViewSpecializeSacadoFad >::value ||
533  std::is_same< typename ViewTraits<T,P...>::specialize ,
534  Kokkos::Impl::ViewSpecializeSacadoFadContiguous >::value )
535  >::type *) {
536  typedef View<T,P...> src_type ;
537  typename src_type::array_layout layout = src.layout();
538  layout.dimension[src_type::rank] = Kokkos::dimension_scalar(src);
539  return typename Impl::MirrorType<Space,T,P ...>::view_type(src.label(),layout);
540 }
541 
542 } // namespace Kokkos
543 
544 //----------------------------------------------------------------------------
545 
546 namespace Kokkos {
547 namespace Impl {
548 
549 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
550 struct FadViewDataAnalysis
551 {
552 private:
553 
554  typedef ViewArrayAnalysis< DataType > array_analysis ;
555 
556 public:
557 
558  // Specialized view data mapping:
559  typedef ViewSpecializeSacadoFad specialize ;
560 
561  typedef typename array_analysis::dimension dimension ;
562  typedef typename array_analysis::value_type value_type ;
563  typedef typename array_analysis::const_value_type const_value_type ;
564  typedef typename array_analysis::non_const_value_type non_const_value_type ;
565 
566  // Generate analogous multidimensional array specification type.
567  typedef typename
568  ViewDataType< value_type , dimension >::type type ;
569  typedef typename
570  ViewDataType< const_value_type , dimension >::type const_type ;
571  typedef typename
572  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
573 
574 private:
575 
576  // A const ?
577  enum { is_const = std::is_same< value_type , const_value_type >::value };
578 
579  // The unwrapped scalar types:
580  typedef typename
581  std::conditional< is_const , const ScalarType , ScalarType >::type
582  scalar_type ;
583 
584  typedef ScalarType non_const_scalar_type ;
585  typedef const ScalarType const_scalar_type ;
586 
587  // Append the FAD static dimension
588  typedef typename array_analysis::dimension::
589  template append<( DimFad ? DimFad + 1 : 0 )>::type
590  scalar_dimension ;
591 
592 public:
593 
594  // Generate "flattened" multidimensional array specification type.
595  typedef typename
596  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
597 
598  typedef typename
599  ViewDataType< const_scalar_type , scalar_dimension >::type
600  const_scalar_array_type ;
601 
602  typedef typename
603  ViewDataType< non_const_scalar_type , scalar_dimension >::type
604  non_const_scalar_array_type ;
605 };
606 
607 // Specialization for LayoutContiguous, where the Fad type is kept contiguous.
608 // This requires a separate view specialization.
609 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad, unsigned Stride >
610 struct FadViewDataAnalysis<DataType, LayoutContiguous<ArrayLayout,Stride>, ScalarType, DimFad>
611 {
612 private:
613 
614  typedef ViewArrayAnalysis< DataType > array_analysis ;
615 
616 public:
617 
618  // For now use the default mapping
619  typedef ViewSpecializeSacadoFadContiguous specialize ;
620 
621  typedef typename array_analysis::dimension dimension ;
622  typedef typename array_analysis::value_type value_type ;
623  typedef typename array_analysis::const_value_type const_value_type ;
624  typedef typename array_analysis::non_const_value_type non_const_value_type ;
625 
626  // Generate analogous multidimensional array specification type.
627  typedef typename
628  ViewDataType< value_type , dimension >::type type ;
629  typedef typename
630  ViewDataType< const_value_type , dimension >::type const_type ;
631  typedef typename
632  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
633 
634 private:
635 
636  // A const ?
637  enum { is_const = std::is_same< value_type , const_value_type >::value };
638 
639  // The unwrapped scalar types:
640  typedef typename
641  std::conditional< is_const , const ScalarType , ScalarType >::type
642  scalar_type ;
643 
644  typedef ScalarType non_const_scalar_type ;
645  typedef const ScalarType const_scalar_type ;
646 
647  // Prepend/append the FAD dimension
648  typedef typename std::conditional<
649  std::is_same< ArrayLayout, Kokkos::LayoutLeft >::value,
650  typename array_analysis::dimension::
651  template prepend<0>::type,
652  typename array_analysis::dimension::
653  template append<0>::type >::type
654  scalar_dimension ;
655 
656 public:
657 
658  // Generate "flattened" multidimensional array specification type.
659  typedef typename
660  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
661 
662  typedef typename
663  ViewDataType< const_scalar_type , scalar_dimension >::type
664  const_scalar_array_type ;
665 
666  typedef typename
667  ViewDataType< non_const_scalar_type , scalar_dimension >::type
668  non_const_scalar_array_type ;
669 
670 };
671 
672 // Specialization for LayoutNatural, where we don't allow striding within
673 // the FadType.
674 //
675 // Currently this is implemented by choosing the default ViewMapping
676 // specialization.
677 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
678 struct FadViewDataAnalysis<DataType, LayoutNatural<ArrayLayout>, ScalarType, DimFad>
679 {
680 private:
681 
682  typedef ViewArrayAnalysis< DataType > array_analysis ;
683 
684 public:
685 
686  // For now use the default mapping
687  typedef void specialize ;
688 
689  typedef typename array_analysis::dimension dimension ;
690  typedef typename array_analysis::value_type value_type ;
691  typedef typename array_analysis::const_value_type const_value_type ;
692  typedef typename array_analysis::non_const_value_type non_const_value_type ;
693 
694  // Generate analogous multidimensional array specification type.
695  typedef typename
696  ViewDataType< value_type , dimension >::type type ;
697  typedef typename
698  ViewDataType< const_value_type , dimension >::type const_type ;
699  typedef typename
700  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
701 
702  // Generate "flattened" multidimensional array specification type.
703  typedef type scalar_array_type ;
704  typedef const_type const_scalar_array_type ;
705  typedef non_const_type non_const_scalar_array_type ;
706 
707 };
708 
709 } // namespace Impl
710 } // namespace Kokkos
711 
712 //----------------------------------------------------------------------------
713 
714 namespace Sacado {
715 
716 namespace Fad { namespace Exp { template< typename > class GeneralFad ; } }
717 
718 #ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
719 namespace Fad { template< typename > class DFad ; }
720 namespace Fad { template< typename , int > class SFad ; }
721 namespace Fad { template< typename , int > class SLFad ; }
722 #endif
723 
724 namespace CacheFad { template< typename > class DFad ; }
725 namespace ELRFad { template< typename > class DFad ; }
726 namespace ELRCacheFad { template< typename > class DFad ; }
727 
728 namespace CacheFad { template< typename , int > class SFad ; }
729 namespace ELRFad { template< typename , int > class SFad ; }
730 namespace ELRCacheFad { template< typename , int > class SFad ; }
731 
732 
733 namespace CacheFad { template< typename , int > class SLFad ; }
734 namespace ELRFad { template< typename , int > class SLFad ; }
735 namespace ELRCacheFad { template< typename , int > class SLFad ; }
736 }
737 
738 namespace Kokkos {
739 namespace Impl {
740 
741 #define KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( NS ) \
742 template< class DataType , class ArrayLayout , typename ScalarType > \
743 struct ViewDataAnalysis \
744  < DataType /* Original view data type */ \
745  , ArrayLayout \
746  , Sacado:: NS ::DFad< ScalarType > \
747  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , 0 > {}; \
748 \
749 template< class DataType , class ArrayLayout , typename ScalarType , int N > \
750 struct ViewDataAnalysis \
751  < DataType /* Original view data type */ \
752  , ArrayLayout \
753  , Sacado:: NS ::SFad< ScalarType , N > \
754  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
755  int(Sacado::StaticSize< Sacado:: NS ::SFad< ScalarType , N > >::value) \
756  > {}; \
757 \
758 template< class DataType , class ArrayLayout , typename ScalarType , int N > \
759 struct ViewDataAnalysis \
760  < DataType /* Original view data type */ \
761  , ArrayLayout \
762  , Sacado:: NS ::SLFad< ScalarType , N > \
763  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
764  int(Sacado::StaticSize< Sacado:: NS ::SLFad< ScalarType , N > >::value) \
765  > {}; \
766 
767 template< class DataType , class ArrayLayout , typename StorageType >
768 struct ViewDataAnalysis
769  < DataType /* Original view data type */
770  , ArrayLayout
771  , Sacado::Fad::Exp::GeneralFad< StorageType >
772  > : public FadViewDataAnalysis< DataType, ArrayLayout, typename StorageType::value_type , 0 > {};
773 
774 #ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
775 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( Fad )
776 #endif
777 
778 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( CacheFad )
779 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRFad )
780 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRCacheFad )
781 
782 #undef KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD
783 
784 } // namespace Impl
785 } // namespace Kokkos
786 
787 //----------------------------------------------------------------------------
788 
789 namespace Kokkos {
790 
791 // Copied from Sacado_ViewFactory
792 template <class View, class ... ViewPack>
794 unsigned dimension_scalar(const View& v, const ViewPack&... views) {
795  const unsigned dim0 = dimension_scalar(v);
796  const unsigned dim1 = dimension_scalar(views...);
797  return dim0 >= dim1 ? dim0 : dim1 ;
798 }
799 
800 } // namespace Kokkos
801 
802 //----------------------------------------------------------------------------
803 
804 namespace Kokkos { namespace Impl {
805 
806 template < typename Specialize, typename A, typename B >
807 struct CommonViewValueType;
808 
809 template < typename A, typename B >
810 struct CommonViewValueType< Kokkos::Impl::ViewSpecializeSacadoFad, A, B >
811 {
812  using value_type = typename Sacado::Promote<A,B>::type ;
813 };
814 
815 template < typename A, typename B >
816 struct CommonViewValueType< Kokkos::Impl::ViewSpecializeSacadoFadContiguous, A, B >
817 {
818  using value_type = typename Sacado::Promote<A,B>::type ;
819 };
820 
821 
822 template < class Specialize, class ValueType >
823 struct CommonViewAllocProp;
824 
825 template < class ValueType >
826 struct CommonViewAllocProp< Kokkos::Impl::ViewSpecializeSacadoFad, ValueType >
827 {
828  using value_type = ValueType;
829  using scalar_array_type = typename Sacado::ValueType< value_type >::type;
830  unsigned fad_dim;
831  bool is_view_type;
832 
834  CommonViewAllocProp()
835  : fad_dim(0) , is_view_type(false) {}
836 
837  // Assume all views are View or DynRankView
838  // TODO If assumption is insufficient, better deduction on is_view...
839  template < class View >
841  CommonViewAllocProp( const View & view )
842  : fad_dim ( dimension_scalar(view) )
843  {
844  is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
845  }
846 
847  // TODO If assumption is insufficient, better deduction on is_view...
848  template < class View, class ... Views >
850  CommonViewAllocProp( const View & view, const Views & ... views )
851  : fad_dim ( dimension_scalar(view, views... ) )
852  {
853  is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
854  }
855 
856 };
857 
858 template < class ValueType >
859 struct CommonViewAllocProp< Kokkos::Impl::ViewSpecializeSacadoFadContiguous, ValueType >
860 {
861  using value_type = ValueType;
862  using scalar_array_type = typename Sacado::ValueType< value_type >::type;
863  unsigned fad_dim;
864  bool is_view_type;
865 
867  CommonViewAllocProp()
868  : fad_dim(0) , is_view_type(false) {}
869 
870  // Assume all views are View or DynRankView
871  // TODO If assumption is insufficient, better deduction on is_view...
872  template < class View >
874  CommonViewAllocProp( const View & view )
875  : fad_dim ( dimension_scalar(view) )
876  {
877  is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
878  }
879 
880  // TODO If assumption is insufficient, better deduction on is_view...
881  template < class View, class ... Views >
883  CommonViewAllocProp( const View & view, const Views & ... views )
884  : fad_dim ( dimension_scalar(view, views... ) )
885  {
886  is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
887  }
888 };
889 
890 // Detect if a ViewCtorProp contains a CommonViewAllocProp
891 template < typename ... P >
892 struct has_common_view_alloc_prop : public std::false_type {};
893 
894 template < class Specialize, class ValueType >
895 struct has_common_view_alloc_prop< CommonViewAllocProp<Specialize, ValueType> > : public std::true_type {};
896 
897 
898 // Check for CommonViewAllocProp in pack of properties
899 template < typename ... >
900 struct check_has_common_view_alloc_prop;
901 
902 template <>
903 struct check_has_common_view_alloc_prop<>
904 {
905  enum { value = false };
906 };
907 
908 template < typename P >
909 struct check_has_common_view_alloc_prop<P>
910 {
911  enum { value = has_common_view_alloc_prop< P >::value };
912 };
913 
914 template < typename P0, typename ... P >
915 struct check_has_common_view_alloc_prop<P0, P...>
916 {
917  enum { value = ( (has_common_view_alloc_prop<P0>::value == true) ? true : check_has_common_view_alloc_prop<P...>::value ) };
918 };
919 
920 template < typename ... >
921 struct compute_fad_dim_from_alloc_prop;
922 
923 template < >
924 struct compute_fad_dim_from_alloc_prop<> {
925  template <typename CtorProp>
927  static unsigned eval(const CtorProp&) { return 0; }
928 };
929 
930 template < typename P >
931 struct compute_fad_dim_from_alloc_prop<P> {
932  template <typename CtorProp>
934  static unsigned eval(const CtorProp&) { return 0; }
935 };
936 
937 template < typename P0, typename ... P >
938 struct compute_fad_dim_from_alloc_prop<P0,P...> {
939  template <typename CtorProp>
941  static unsigned eval(const CtorProp& prop) {
942  unsigned d1 = compute_fad_dim_from_alloc_prop<P0>::eval(prop);
943  unsigned d2 = compute_fad_dim_from_alloc_prop<P...>::eval(prop);
944  return d1 > d2 ? d1 : d2;
945  }
946 };
947 
948 template < class ValueType >
949 struct compute_fad_dim_from_alloc_prop<
950  CommonViewAllocProp<ViewSpecializeSacadoFad, ValueType>
951  > {
952  template <typename CtorProp>
954  static unsigned eval(const CtorProp& prop) {
955  using specialize = ViewSpecializeSacadoFad;
956  using CVAP = CommonViewAllocProp< specialize, ValueType >;
957  auto cast_prop = ((Kokkos::Impl::ViewCtorProp<void, CVAP> const &)prop).value;
958  return cast_prop.fad_dim;
959  }
960 };
961 
962 template < class ValueType >
963 struct compute_fad_dim_from_alloc_prop<
964  CommonViewAllocProp<ViewSpecializeSacadoFadContiguous, ValueType>
965  > {
966  template <typename CtorProp>
968  static unsigned eval(const CtorProp& prop) {
969  using specialize = ViewSpecializeSacadoFadContiguous;
970  using CVAP = CommonViewAllocProp< specialize, ValueType >;
971  auto cast_prop = ((Kokkos::Impl::ViewCtorProp<void, CVAP> const &)prop).value;
972  return cast_prop.fad_dim;
973  }
974 };
975 
976 template <typename Traits, typename ... P >
977 struct appendFadToLayoutViewAllocHelper
978 {
979  using layout_type = typename Traits::array_layout;
980  using specialize = typename Traits::specialize;
981  using CtorProp = ViewCtorProp< P... >;
982 
984  static layout_type returnNewLayoutPlusFad( const CtorProp & arg_prop, const layout_type & arg_layout ) {
985 
986  layout_type appended_layout( arg_layout );
987 
988  // Static View case - DynRankView layout handled within createLayout calls
989 
990  const unsigned fad_dim =
991  compute_fad_dim_from_alloc_prop<P...>::eval(arg_prop);
992  appended_layout.dimension[ Traits::rank ] = (fad_dim > 0) ? fad_dim : 1;
993 
994  return appended_layout;
995  }
996 };
997 
998 template <typename Layout>
999 struct prependFadToLayout
1000 {
1001  using layout_type = Layout;
1002 
1003  template < typename FadSizeType >
1005  static layout_type returnNewLayoutPlusFad( const layout_type & arg_layout, const FadSizeType fad_dim ) {
1006 
1007  layout_type prepended_layout(0,0,0,0,0,0,0,0);
1008 
1009  prepended_layout.dimension[0] = fad_dim;
1010 
1011  for ( int i = 1; i < ARRAY_LAYOUT_MAX_RANK; ++i ) {
1012  prepended_layout.dimension[i] = arg_layout.dimension[i-1];
1013  }
1014 
1015  return prepended_layout;
1016  }
1017 };
1018 
1019 } } // namespace Kokkos::Impl
1020 
1021 
1022 //----------------------------------------------------------------------------
1023 
1024 
1025 namespace Kokkos {
1026 namespace Impl {
1027 
1028 template< class Traits >
1029 class ViewMapping< Traits , /* View internal mapping */
1030  typename std::enable_if<
1031  ( std::is_same< typename Traits::specialize
1032  , ViewSpecializeSacadoFad >::value
1033  &&
1034  ( std::is_same< typename Traits::array_layout
1035  , Kokkos::LayoutLeft >::value
1036  ||
1037  std::is_same< typename Traits::array_layout
1038  , Kokkos::LayoutRight >::value
1039  ||
1040  std::is_same< typename Traits::array_layout
1041  , Kokkos::LayoutStride >::value
1042  )
1043  )
1044  , typename Traits::specialize
1045  >::type >
1046 {
1047 private:
1048 
1049  template< class , class ... > friend class ViewMapping ;
1050  template< class , class ... > friend class Kokkos::View ;
1051 
1052  typedef typename Traits::value_type fad_type ;
1053  typedef typename Sacado::ValueType< fad_type >::type fad_value_type ;
1054  typedef typename
1055  std::add_const< fad_value_type >::type const_fad_value_type ;
1056 
1057  enum { FadStaticDimension = Sacado::StaticSize< fad_type >::value };
1059 
1060  // Only LayoutRight has a static stride one
1061  enum { FadStaticStride =
1062  std::is_same< typename Traits::array_layout
1063  , Kokkos::LayoutRight >::value ? 1 : 0 };
1064 
1065  typedef Sacado::integral_nonzero< unsigned , FadStaticStride > sacado_stride_type;
1066 
1067  typedef fad_value_type * handle_type ;
1068 
1069  typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
1070 
1071  // Offset without Fad dimension
1072  typedef ViewOffset< typename Traits::dimension
1073  , typename Traits::array_layout
1074  , void
1075  > offset_type ;
1076 
1077  // Append the fad dimension for the internal offset mapping.
1078  typedef ViewOffset
1079  < typename array_analysis::dimension::
1080  template append<( unsigned(FadStaticDimension) > 0 ? unsigned(FadStaticDimension) + 1 : 0 )>::type
1081  , typename Traits::array_layout
1082  , void
1083  > array_offset_type ;
1084 
1085  handle_type m_impl_handle ;
1086  offset_type m_impl_offset ;
1087  array_offset_type m_array_offset ;
1088  sacado_size_type m_fad_size ;
1089  sacado_stride_type m_fad_stride ;
1090 
1091 public:
1092 
1093  //----------------------------------------
1094  // Domain dimensions
1095 
1096  enum { Rank = Traits::dimension::rank };
1097 
1098  // Using the internal offset mapping so limit to public rank:
1099  template< typename iType >
1100  KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
1101  { return m_impl_offset.m_dim.extent(r) ; }
1102 
1103  KOKKOS_INLINE_FUNCTION constexpr
1104  typename Traits::array_layout layout() const
1105  { return m_impl_offset.layout(); }
1106 
1107  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
1108  { return m_impl_offset.dimension_0(); }
1109  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
1110  { return m_impl_offset.dimension_1(); }
1111  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
1112  { return m_impl_offset.dimension_2(); }
1113  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
1114  { return m_impl_offset.dimension_3(); }
1115  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
1116  { return m_impl_offset.dimension_4(); }
1117  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
1118  { return m_impl_offset.dimension_5(); }
1119  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
1120  { return m_impl_offset.dimension_6(); }
1121  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
1122  { return m_impl_offset.dimension_7(); }
1123 
1124  // Can only be regular layout with uniform striding
1125  // when LayoutRight with contiguous values so not guaranteed true.
1126  using is_regular = std::false_type ;
1127 
1128  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const
1129  { return m_impl_offset.stride_0(); }
1130  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const
1131  { return m_impl_offset.stride_1(); }
1132  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const
1133  { return m_impl_offset.stride_2(); }
1134  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const
1135  { return m_impl_offset.stride_3(); }
1136  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const
1137  { return m_impl_offset.stride_4(); }
1138  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const
1139  { return m_impl_offset.stride_5(); }
1140  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const
1141  { return m_impl_offset.stride_6(); }
1142  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const
1143  { return m_impl_offset.stride_7(); }
1144 
1145  template< typename iType >
1146  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const
1147  { m_impl_offset.stride(s) ; }
1148 
1149  // Size of sacado scalar dimension
1150  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
1151  { return m_fad_size.value+1; }
1152 
1153  // trode of sacado scalar dimension
1154  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned stride_scalar() const
1155  { return m_fad_stride.value; }
1156 
1157  //----------------------------------------
1158  // Range of mapping
1159 
1160  // Return type of reference operators
1161  typedef typename
1163 
1165  typedef fad_value_type * pointer_type ;
1166 
1168  KOKKOS_INLINE_FUNCTION constexpr size_t span() const
1169  { return m_array_offset.span(); }
1170 
1172  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
1173  { return m_array_offset.span_is_contiguous() ; }
1174 
1176  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
1177  { return m_impl_handle ; }
1178 
1179  //----------------------------------------
1180 
1182  reference_type reference() const
1183  { return reference_type( m_impl_handle
1184  , m_fad_size.value
1185  , m_fad_stride.value ); }
1186 
1187  template< typename I0 >
1189  reference_type
1190  reference( const I0 & i0 ) const
1191  { return reference_type( m_impl_handle + m_array_offset(i0,0)
1192  , m_fad_size.value
1193  , m_fad_stride.value ); }
1194 
1195  template< typename I0 , typename I1 >
1197  reference_type reference( const I0 & i0 , const I1 & i1 ) const
1198  { return reference_type( m_impl_handle + m_array_offset(i0,i1,0)
1199  , m_fad_size.value
1200  , m_fad_stride.value ); }
1201 
1202 
1203  template< typename I0 , typename I1 , typename I2 >
1205  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
1206  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,0)
1207  , m_fad_size.value
1208  , m_fad_stride.value ); }
1209 
1210  template< typename I0 , typename I1 , typename I2 , typename I3 >
1212  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
1213  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,0)
1214  , m_fad_size.value
1215  , m_fad_stride.value ); }
1216 
1217  template< typename I0 , typename I1 , typename I2 , typename I3
1218  , typename I4 >
1220  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1221  , const I4 & i4 ) const
1222  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,0)
1223  , m_fad_size.value
1224  , m_fad_stride.value ); }
1225 
1226  template< typename I0 , typename I1 , typename I2 , typename I3
1227  , typename I4 , typename I5 >
1229  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1230  , const I4 & i4 , const I5 & i5 ) const
1231  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,i5,0)
1232  , m_fad_size.value
1233  , m_fad_stride.value ); }
1234 
1235 
1236  template< typename I0 , typename I1 , typename I2 , typename I3
1237  , typename I4 , typename I5 , typename I6 >
1239  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1240  , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
1241  { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,i5,i6,0)
1242  , m_fad_size.value
1243  , m_fad_stride.value ); }
1244 
1245  //----------------------------------------
1246 
1249  static size_t memory_span( typename Traits::array_layout const & layout )
1250  {
1251  size_t dims[8];
1252  for (int i=0; i<8; ++i)
1253  dims[i] = layout.dimension[i];
1254  if (unsigned(FadStaticDimension) > 0)
1255  dims[unsigned(Rank)] = FadStaticDimension+1;
1256 
1257  typename Traits::array_layout alayout(
1258  dims[0], dims[1], dims[2], dims[3],
1259  dims[4], dims[5], dims[6], dims[7] );
1260 
1261  // Do not introduce padding...
1262  typedef std::integral_constant< unsigned , 0 > padding ;
1263  return array_offset_type( padding() , alayout ).span() * sizeof(fad_value_type);
1264  }
1265 
1266  //----------------------------------------
1267 
1268  KOKKOS_INLINE_FUNCTION ~ViewMapping() {}
1269  KOKKOS_INLINE_FUNCTION ViewMapping() : m_impl_handle(0) , m_impl_offset() , m_array_offset() , m_fad_size(0) , m_fad_stride(0) {}
1270 
1271  KOKKOS_DEFAULTED_FUNCTION ViewMapping( const ViewMapping & ) = default ;
1272  KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
1273 
1274  KOKKOS_DEFAULTED_FUNCTION ViewMapping( ViewMapping && ) = default ;
1275  KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
1276 
1277  template< class ... P >
1279  ViewMapping
1280  ( ViewCtorProp< P ... > const & prop
1281  , typename Traits::array_layout const & local_layout
1282  )
1283  : m_impl_handle( ( (ViewCtorProp<void,pointer_type> const &) prop ).value )
1284  , m_impl_offset( std::integral_constant< unsigned , 0 >()
1285  , local_layout )
1286  , m_array_offset( std::integral_constant< unsigned , 0 >()
1287  , local_layout )
1288  // Query m_array_offset, not input, in case of static dimension
1289  , m_fad_size(
1290  ( Rank == 0 ? m_array_offset.dimension_0() :
1291  ( Rank == 1 ? m_array_offset.dimension_1() :
1292  ( Rank == 2 ? m_array_offset.dimension_2() :
1293  ( Rank == 3 ? m_array_offset.dimension_3() :
1294  ( Rank == 4 ? m_array_offset.dimension_4() :
1295  ( Rank == 5 ? m_array_offset.dimension_5() :
1296  ( Rank == 6 ? m_array_offset.dimension_6() :
1297  m_array_offset.dimension_7() ))))))) - 1 )
1298  , m_fad_stride(
1299  ( Rank == 0 ? m_array_offset.stride_0() :
1300  ( Rank == 1 ? m_array_offset.stride_1() :
1301  ( Rank == 2 ? m_array_offset.stride_2() :
1302  ( Rank == 3 ? m_array_offset.stride_3() :
1303  ( Rank == 4 ? m_array_offset.stride_4() :
1304  ( Rank == 5 ? m_array_offset.stride_5() :
1305  ( Rank == 6 ? m_array_offset.stride_6() :
1306  m_array_offset.stride_7() ))))))))
1307 
1308  {
1309  const unsigned fad_dim =
1310  ( Rank == 0 ? m_array_offset.dimension_0() :
1311  ( Rank == 1 ? m_array_offset.dimension_1() :
1312  ( Rank == 2 ? m_array_offset.dimension_2() :
1313  ( Rank == 3 ? m_array_offset.dimension_3() :
1314  ( Rank == 4 ? m_array_offset.dimension_4() :
1315  ( Rank == 5 ? m_array_offset.dimension_5() :
1316  ( Rank == 6 ? m_array_offset.dimension_6() :
1317  m_array_offset.dimension_7() )))))));
1318  if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
1319  Kokkos::abort("invalid fad dimension (0) supplied!");
1320  }
1321 
1322  //----------------------------------------
1323  /* Allocate and construct mapped array.
1324  * Allocate via shared allocation record and
1325  * return that record for allocation tracking.
1326  */
1327  template< class ... P >
1328  SharedAllocationRecord<> *
1329  allocate_shared( ViewCtorProp< P... > const & prop
1330  , typename Traits::array_layout const & local_layout )
1331  {
1332  typedef ViewCtorProp< P... > ctor_prop ;
1333 
1334  typedef typename ctor_prop::execution_space execution_space ;
1335  typedef typename Traits::memory_space memory_space ;
1336  typedef ViewValueFunctor< execution_space , fad_value_type > functor_type ;
1337  typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
1338 
1339  // Disallow padding
1340  typedef std::integral_constant< unsigned , 0 > padding ;
1341 
1342  // Check if ViewCtorProp has CommonViewAllocProp - if so, retrieve the fad_size and append to layout
1343  enum { test_traits_check = Kokkos::Impl::check_has_common_view_alloc_prop< P... >::value };
1344 
1345  m_impl_offset = offset_type( padding(), local_layout );
1346 
1347  typename Traits::array_layout internal_layout =
1348  (test_traits_check == true)
1349  ? Kokkos::Impl::appendFadToLayoutViewAllocHelper< Traits, P... >::returnNewLayoutPlusFad(prop, local_layout)
1350  : local_layout;
1351 
1352  m_array_offset = array_offset_type( padding(), internal_layout );
1353 
1354  const unsigned fad_dim =
1355  ( Rank == 0 ? m_array_offset.dimension_0() :
1356  ( Rank == 1 ? m_array_offset.dimension_1() :
1357  ( Rank == 2 ? m_array_offset.dimension_2() :
1358  ( Rank == 3 ? m_array_offset.dimension_3() :
1359  ( Rank == 4 ? m_array_offset.dimension_4() :
1360  ( Rank == 5 ? m_array_offset.dimension_5() :
1361  ( Rank == 6 ? m_array_offset.dimension_6() :
1362  m_array_offset.dimension_7() )))))));
1363  if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
1364  Kokkos::abort("invalid fad dimension (0) supplied!");
1365  m_fad_size = fad_dim - 1 ;
1366 
1367  m_fad_stride =
1368  ( Rank == 0 ? m_array_offset.stride_0() :
1369  ( Rank == 1 ? m_array_offset.stride_1() :
1370  ( Rank == 2 ? m_array_offset.stride_2() :
1371  ( Rank == 3 ? m_array_offset.stride_3() :
1372  ( Rank == 4 ? m_array_offset.stride_4() :
1373  ( Rank == 5 ? m_array_offset.stride_5() :
1374  ( Rank == 6 ? m_array_offset.stride_6() :
1375  m_array_offset.stride_7() )))))));
1376 
1377  const size_t alloc_size = m_array_offset.span() * sizeof(fad_value_type);
1378 
1379  // Create shared memory tracking record with allocate memory from the memory space
1380  record_type * const record =
1381  record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
1382  , ( (ViewCtorProp<void,std::string> const &) prop ).value
1383  , alloc_size );
1384 
1385  // Only set the the pointer and initialize if the allocation is non-zero.
1386  // May be zero if one of the dimensions is zero.
1387  if ( alloc_size ) {
1388 
1389  m_impl_handle = handle_type( reinterpret_cast< pointer_type >( record->data() ) );
1390 
1391  if ( ctor_prop::initialize ) {
1392  // Assume destruction is only required when construction is requested.
1393  // The ViewValueFunctor has both value construction and destruction operators.
1394  record->m_destroy = functor_type( ( (ViewCtorProp<void,execution_space> const &) prop).value
1395  , (fad_value_type *) m_impl_handle
1396  , m_array_offset.span()
1397  );
1398 
1399  // Construct values
1400  record->m_destroy.construct_shared_allocation();
1401  }
1402  }
1403 
1404  return record ;
1405  }
1406 
1407 };
1408 
1409 } // namespace Impl
1410 } // namespace Kokkos
1411 
1412 //----------------------------------------------------------------------------
1413 
1414 namespace Kokkos {
1415 namespace Impl {
1416 
1421 template< class DstTraits , class SrcTraits >
1422 class ViewMapping< DstTraits , SrcTraits ,
1423  typename std::enable_if<(
1424  Kokkos::Impl::MemorySpaceAccess
1425  < typename DstTraits::memory_space
1426  , typename SrcTraits::memory_space >::assignable
1427  &&
1428  // Destination view has FAD
1429  std::is_same< typename DstTraits::specialize
1430  , ViewSpecializeSacadoFad >::value
1431  &&
1432  // Source view has FAD
1433  std::is_same< typename SrcTraits::specialize
1434  , ViewSpecializeSacadoFad >::value
1435 
1436  )
1437  , typename DstTraits::specialize
1438  >::type >
1439 {
1440 public:
1441 
1442  enum { is_assignable = true };
1443  enum { is_assignable_data_type = true };
1444 
1445  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1446  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1447  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1448 
1449  template< class DstType >
1450  KOKKOS_INLINE_FUNCTION static
1451  void assign( DstType & dst
1452  , const SrcFadType & src
1453  , const TrackType & )
1454  {
1455  static_assert(
1456  (
1457  std::is_same< typename DstTraits::array_layout
1458  , Kokkos::LayoutLeft >::value ||
1459  std::is_same< typename DstTraits::array_layout
1460  , Kokkos::LayoutRight >::value ||
1461  std::is_same< typename DstTraits::array_layout
1462  , Kokkos::LayoutStride >::value
1463  )
1464  &&
1465  (
1466  std::is_same< typename SrcTraits::array_layout
1467  , Kokkos::LayoutLeft >::value ||
1468  std::is_same< typename SrcTraits::array_layout
1469  , Kokkos::LayoutRight >::value ||
1470  std::is_same< typename SrcTraits::array_layout
1471  , Kokkos::LayoutStride >::value
1472  )
1473  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1474 
1475  static_assert(
1476  std::is_same< typename DstTraits::array_layout
1477  , typename SrcTraits::array_layout >::value ||
1478  std::is_same< typename DstTraits::array_layout
1479  , Kokkos::LayoutStride >::value ,
1480  "View assignment must have compatible layout" );
1481 
1482  static_assert(
1483  std::is_same< typename DstTraits::scalar_array_type
1484  , typename SrcTraits::scalar_array_type >::value ||
1485  std::is_same< typename DstTraits::scalar_array_type
1486  , typename SrcTraits::const_scalar_array_type >::value ,
1487  "View assignment must have same value type or const = non-const" );
1488 
1489  static_assert(
1490  ViewDimensionAssignable
1491  < typename DstType::offset_type::dimension_type
1492  , typename SrcFadType::offset_type::dimension_type >::value ,
1493  "View assignment must have compatible dimensions" );
1494 
1495  static_assert(
1496  ViewDimensionAssignable
1497  < typename DstType::array_offset_type::dimension_type
1498  , typename SrcFadType::array_offset_type::dimension_type >::value ,
1499  "View assignment must have compatible dimensions" );
1500 
1501  typedef typename DstType::offset_type dst_offset_type ;
1502  typedef typename DstType::array_offset_type dst_array_offset_type ;
1503 
1504  dst.m_impl_handle = src.m_impl_handle ;
1505  dst.m_impl_offset = dst_offset_type( src.m_impl_offset );
1506  dst.m_array_offset = dst_array_offset_type( src.m_array_offset );
1507  dst.m_fad_size = src.m_fad_size.value ;
1508  dst.m_fad_stride = src.m_fad_stride.value ;
1509  }
1510 };
1511 
1512 // Integer argument is the actual rank => ranks 0 to Rank-1 will be assigned
1518 template< class DstTraits , class SrcTraits >
1519 class ViewMapping< DstTraits , SrcTraits ,
1520  typename std::enable_if<(
1521  Kokkos::Impl::MemorySpaceAccess
1522  < typename DstTraits::memory_space
1523  , typename SrcTraits::memory_space >::assignable
1524  &&
1525  // Destination view has ordinary
1526  std::is_same< typename DstTraits::specialize , void >::value
1527  &&
1528  // Source view has FAD only
1529  std::is_same< typename SrcTraits::specialize
1530  , ViewSpecializeSacadoFad >::value
1531  )
1532  , typename DstTraits::specialize
1533  >::type >
1534 {
1535 public:
1536 
1537  enum { is_assignable = true };
1538  enum { is_assignable_data_type = true };
1539 
1540 
1541  typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1542  typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1543  typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1544 
1545 
1546  // Helpers to assign, and generate if necessary, ViewOffset to the dst map
1547  // These are necessary to use Kokkos' deep_copy with nested fads
1548  template < class DstType, class SrcFadType, class Truth = void >
1549  struct AssignOffset;
1550 
1551  template < class DstType, class SrcFadType >
1552  struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank != (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
1553  {
1554  // ViewOffset's Dimensions Ranks do not match
1556  static void assign( DstType & dst, const SrcFadType & src )
1557  {
1558  typedef typename SrcTraits::value_type TraitsValueType;
1559 
1562  )
1563  {
1564  typedef typename DstType::offset_type::array_layout DstLayoutType;
1565  //typedef typename ViewArrayLayoutSelector<typename DstType::offset_type::array_layout>::type DstLayoutType;
1566  typedef typename SrcFadType::array_offset_type::dimension_type SrcViewDimension;
1567 
1568  // This is the static dimension of the inner fad, missing from ViewDimension
1569  const size_t InnerStaticDim = Sacado::StaticSize< typename Sacado::ValueType< TraitsValueType >::type >::value;
1570 
1571  static constexpr bool is_layout_left =
1572  std::is_same< DstLayoutType, Kokkos::LayoutLeft>::value;
1573 
1574  typedef typename std::conditional< is_layout_left,
1575  typename SrcViewDimension:: template prepend< InnerStaticDim+1 >::type,
1576  typename SrcViewDimension:: template append < InnerStaticDim+1 >::type
1577  >::type SrcViewDimensionAppended;
1578 
1579  typedef std::integral_constant< unsigned , 0 > padding ;
1580 
1581  typedef ViewOffset< SrcViewDimensionAppended, DstLayoutType > TmpOffsetType;
1582 
1583  auto src_layout = src.m_array_offset.layout();
1584 
1585  if ( is_layout_left ) {
1586  auto prepend_layout = Kokkos::Impl::prependFadToLayout< DstLayoutType >::returnNewLayoutPlusFad(src_layout, InnerStaticDim+1);
1587  TmpOffsetType offset_tmp( padding(), prepend_layout );
1588  dst.m_impl_offset = offset_tmp;
1589  }
1590  else {
1591  TmpOffsetType offset_tmp( padding(), src_layout );
1592  dst.m_impl_offset = offset_tmp;
1593  }
1594 
1595  } else {
1596  Kokkos::abort("Sacado error: Applying AssignOffset for case with nested Fads, but without nested Fads - something went wrong");
1597  }
1598  }
1599  };
1600 
1601  template < class DstType, class SrcFadType >
1602  struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank == (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
1603  {
1605  static void assign( DstType & dst, const SrcFadType & src )
1606  {
1607 
1608  typedef typename DstType::offset_type dst_offset_type ;
1609  dst.m_impl_offset = dst_offset_type( src.m_array_offset );
1610  }
1611  };
1612 
1613 
1614 // If the dst and src mappings are not equal in Rank, the src should come from a View of nested fads
1615 // In the case of two nested fads, the innermost must be an SFad (static Fad)
1616 // The offset_type's are not compatible in the case of nested fads because the ViewDimension's ranks will not agree
1617 // In this case, rather than trying to construct an offset_type from src (which will fail at compile time)
1618 // and assign to dst.m_impl_offset, manually assign the ViewDimension arguments to dst;
1619 // requires appending the missing inner SFad dim + 1 to the Rank-1 ViewDimension
1620  // DstType and SrcFadType are MAPS...
1621  template < class DstType >
1622  KOKKOS_INLINE_FUNCTION static
1623  void
1624  assign( DstType & dst
1625  , const SrcFadType & src
1626  , const TrackType &
1627  )
1628  {
1629 
1630  static_assert(
1631  (
1632  std::is_same< typename DstTraits::array_layout
1633  , Kokkos::LayoutLeft >::value ||
1634  std::is_same< typename DstTraits::array_layout
1635  , Kokkos::LayoutRight >::value ||
1636  std::is_same< typename DstTraits::array_layout
1637  , Kokkos::LayoutStride >::value
1638  )
1639  &&
1640  (
1641  std::is_same< typename SrcTraits::array_layout
1642  , Kokkos::LayoutLeft >::value ||
1643  std::is_same< typename SrcTraits::array_layout
1644  , Kokkos::LayoutRight >::value ||
1645  std::is_same< typename SrcTraits::array_layout
1646  , Kokkos::LayoutStride >::value
1647  )
1648  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1649 
1650  static_assert(
1651  std::is_same< typename DstTraits::array_layout
1652  , typename SrcTraits::array_layout >::value ||
1653  std::is_same< typename DstTraits::array_layout
1654  , Kokkos::LayoutStride >::value ,
1655  "View assignment must have compatible layout" );
1656 #if 0
1657  static_assert(
1658  std::is_same< typename DstTraits::scalar_array_type
1659  , typename SrcTraits::scalar_array_type >::value ||
1660  std::is_same< typename DstTraits::scalar_array_type
1661  , typename SrcTraits::const_scalar_array_type >::value ,
1662  "View assignment must have same value type or const = non-const" );
1663 #endif
1664 
1665  AssignOffset< DstType, SrcFadType >::assign( dst, src );
1666 
1667  dst.m_impl_handle = reinterpret_cast< typename DstType::handle_type >(src.m_impl_handle) ;
1668  }
1669 };
1670 
1671 } // namespace Impl
1672 } // namespace Kokkos
1673 
1674 //----------------------------------------------------------------------------
1675 
1676 namespace Kokkos {
1677 namespace Impl {
1678 
1679 // Subview mapping
1680 
1681 template< class SrcTraits , class ... Args >
1682 struct ViewMapping
1683  < typename std::enable_if<(
1684  // Source view has FAD only
1685  std::is_same< typename SrcTraits::specialize
1686  , ViewSpecializeSacadoFad >::value
1687  &&
1688  (
1689  std::is_same< typename SrcTraits::array_layout
1690  , Kokkos::LayoutLeft >::value ||
1691  std::is_same< typename SrcTraits::array_layout
1692  , Kokkos::LayoutRight >::value ||
1693  std::is_same< typename SrcTraits::array_layout
1694  , Kokkos::LayoutStride >::value
1695  )
1696  )
1697  >::type
1698  , SrcTraits
1699  , Args ... >
1700 {
1701 private:
1702 
1703  static_assert( SrcTraits::rank == sizeof...(Args) , "" );
1704 
1705  enum
1706  { RZ = false
1707  , R0 = bool(is_integral_extent<0,Args...>::value)
1708  , R1 = bool(is_integral_extent<1,Args...>::value)
1709  , R2 = bool(is_integral_extent<2,Args...>::value)
1710  , R3 = bool(is_integral_extent<3,Args...>::value)
1711  , R4 = bool(is_integral_extent<4,Args...>::value)
1712  , R5 = bool(is_integral_extent<5,Args...>::value)
1713  , R6 = bool(is_integral_extent<6,Args...>::value)
1714  };
1715 
1716  // Public rank
1717  enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
1718  + unsigned(R4) + unsigned(R5) + unsigned(R6) };
1719 
1720  // Whether right-most non-FAD rank is a range.
1721  enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
1722  1 == SrcTraits::rank ? R0 : (
1723  2 == SrcTraits::rank ? R1 : (
1724  3 == SrcTraits::rank ? R2 : (
1725  4 == SrcTraits::rank ? R3 : (
1726  5 == SrcTraits::rank ? R4 : (
1727  6 == SrcTraits::rank ? R5 : R6 ))))))) };
1728 
1729  // Subview's layout
1730  // If LayoutRight then FAD is contiguous
1731  // For LayoutLeft, result is LayoutLeft only if 1st arg is a range,
1732  // and since last (FAD) dimension is also a range, and these
1733  // ranges must be consecutive, the input rank must be 1
1734  typedef typename std::conditional<
1735  ( /* Same layout IF */
1736  ( rank == 0 )
1737  ||
1738  ( std::is_same< typename SrcTraits::array_layout
1739  , Kokkos::LayoutRight >::value
1740  &&
1741  ( rank == 1 ) && R0_rev
1742  )
1743  ||
1744  ( std::is_same< typename SrcTraits::array_layout
1745  , Kokkos::LayoutLeft >::value
1746  &&
1747  ( rank == 1 ) && (SrcTraits::rank == 1) && R0
1748  )
1749  ), typename SrcTraits::array_layout , Kokkos::LayoutStride
1750  >::type array_layout ;
1751 
1752  typedef typename SrcTraits::value_type fad_type ;
1753 
1754  typedef typename std::conditional< rank == 0 , fad_type ,
1755  typename std::conditional< rank == 1 , fad_type * ,
1756  typename std::conditional< rank == 2 , fad_type ** ,
1757  typename std::conditional< rank == 3 , fad_type *** ,
1758  typename std::conditional< rank == 4 , fad_type **** ,
1759  typename std::conditional< rank == 5 , fad_type ***** ,
1760  typename std::conditional< rank == 6 , fad_type ****** ,
1761  fad_type *******
1762  >::type >::type >::type >::type >::type >::type >::type
1763  data_type ;
1764 
1765 public:
1766 
1767  typedef Kokkos::ViewTraits
1768  < data_type
1769  , array_layout
1770  , typename SrcTraits::device_type
1771  , typename SrcTraits::memory_traits > traits_type ;
1772 
1773  typedef Kokkos::View
1774  < data_type
1775  , array_layout
1776  , typename SrcTraits::device_type
1777  , typename SrcTraits::memory_traits > type ;
1778 
1779 
1781  static void assign( ViewMapping< traits_type , typename traits_type::specialize > & dst
1782  , ViewMapping< SrcTraits ,typename SrcTraits::specialize > const & src
1783  , Args ... args )
1784  {
1785  typedef ViewMapping< traits_type , typename traits_type::specialize > DstType ;
1786  typedef typename DstType::offset_type dst_offset_type ;
1787  typedef typename DstType::array_offset_type dst_array_offset_type ;
1788  typedef typename DstType::handle_type dst_handle_type ;
1789 
1790  const SubviewExtents< SrcTraits::rank , rank >
1791  extents( src.m_impl_offset.m_dim , args... );
1792  const SubviewExtents< SrcTraits::rank + 1 , rank + 1 >
1793  array_extents( src.m_array_offset.m_dim , args... , Kokkos::ALL() );
1794 
1795  dst.m_impl_offset = dst_offset_type( src.m_impl_offset , extents );
1796  dst.m_array_offset = dst_array_offset_type( src.m_array_offset , array_extents );
1797  dst.m_impl_handle =
1798  dst_handle_type( src.m_impl_handle +
1799  src.m_array_offset( array_extents.domain_offset(0)
1800  , array_extents.domain_offset(1)
1801  , array_extents.domain_offset(2)
1802  , array_extents.domain_offset(3)
1803  , array_extents.domain_offset(4)
1804  , array_extents.domain_offset(5)
1805  , array_extents.domain_offset(6)
1806  , array_extents.domain_offset(7) ) );
1807  dst.m_fad_size = src.m_fad_size;
1808  dst.m_fad_stride = src.m_fad_stride.value;
1809  }
1810 
1811 };
1812 
1813 } // namespace Impl
1814 } // namespace Kokkos
1815 
1816 //----------------------------------------------------------------------------
1817 //----------------------------------------------------------------------------
1818 
1819 #if defined(HAVE_SACADO_KOKKOSCORE) && \
1820  defined(HAVE_SACADO_TEUCHOSKOKKOSCOMM) && \
1821  defined(HAVE_SACADO_VIEW_SPEC) && \
1822  ! defined(SACADO_DISABLE_FAD_VIEW_SPEC)
1823 
1824 #include "Kokkos_TeuchosCommAdapters.hpp"
1825 
1826 namespace Teuchos {
1827 
1828 template< typename Ordinal , class SD , class ... SP , class RD , class ... RP >
1829 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
1830  Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
1831  >::type
1832 reduceAll
1833  ( const Comm<Ordinal>& comm,
1834  const EReductionType reductType ,
1835  const Ordinal count,
1836  const Kokkos::View<SD,SP...> & sendBuffer ,
1837  const Kokkos::View<RD,RP...> & recvBuffer )
1838 {
1839  // We can't implement reduceAll by extracting the underlying array (since we
1840  // can't reduce across the derivative dimension) and we can't just extract
1841  // a pointer due to ViewFad. In principle we could handle ViewFad in the
1842  // serializer, but for the time being we just copy the view's into local
1843  // buffers (on the host).
1844  typedef Kokkos::View<SD,SP...> SendViewType;
1845  typedef Kokkos::View<RD,RP...> RecvViewType;
1846  typedef typename SendViewType::value_type send_value_type;
1847  typedef typename RecvViewType::value_type recv_value_type;
1848 
1849  TEUCHOS_TEST_FOR_EXCEPTION(
1850  SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
1851  "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
1852  "The send View's rank is " << SendViewType::rank << " and the receive "
1853  "View's rank is " << RecvViewType::rank << ".");
1854 
1855  // Copy send buffer into local array
1856  Teuchos::Array<send_value_type> localSendBuffer(count);
1857  typename SendViewType::HostMirror hostSendBuffer =
1858  Kokkos::create_mirror_view(sendBuffer);
1859  Kokkos::deep_copy(hostSendBuffer, sendBuffer);
1860  for (Ordinal i=0; i<count; ++i)
1861  localSendBuffer[i] = hostSendBuffer(i);
1862 
1863  // Copy receive buffer into local array (necessary to initialize Fad types
1864  // properly)
1865  Teuchos::Array<recv_value_type> localRecvBuffer(count);
1866  typename RecvViewType::HostMirror hostRecvBuffer =
1867  Kokkos::create_mirror_view(recvBuffer);
1868  Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
1869  for (Ordinal i=0; i<count; ++i)
1870  localRecvBuffer[i] = hostRecvBuffer(i);
1871 
1872  // Do reduce-all
1873  reduceAll(comm, reductType, count,
1874  localSendBuffer.getRawPtr(),
1875  localRecvBuffer.getRawPtr());
1876 
1877  // Copy back into original buffer
1878  for (Ordinal i=0; i<count; ++i)
1879  hostRecvBuffer(i) = localRecvBuffer[i];
1880  Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
1881 }
1882 
1883 
1884 template< typename Ordinal , typename Serializer ,
1885  class SD , class ... SP , class RD , class ... RP >
1886 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
1887  Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
1888  >::type
1889 reduceAll
1890  ( const Comm<Ordinal>& comm,
1891  const Serializer& serializer,
1892  const EReductionType reductType ,
1893  const Ordinal count,
1894  const Kokkos::View<SD,SP...> & sendBuffer ,
1895  const Kokkos::View<RD,RP...> & recvBuffer )
1896 {
1897  // We can't implement reduceAll by extracting the underlying array (since we
1898  // can't reduce across the derivative dimension) and we can't just extract
1899  // a pointer due to ViewFad. In principle we could handle ViewFad in the
1900  // serializer, but for the time being we just copy the view's into local
1901  // buffers (on the host).
1902  typedef Kokkos::View<SD,SP...> SendViewType;
1903  typedef Kokkos::View<RD,RP...> RecvViewType;
1904  typedef typename SendViewType::value_type send_value_type;
1905  typedef typename RecvViewType::value_type recv_value_type;
1906 
1907  TEUCHOS_TEST_FOR_EXCEPTION(
1908  SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
1909  "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
1910  "The send View's rank is " << SendViewType::rank << " and the receive " "View's rank is " << RecvViewType::rank << ".");
1911 
1912  // Copy send buffer into local array
1913  Teuchos::Array<send_value_type> localSendBuffer(count);
1914  typename SendViewType::HostMirror hostSendBuffer =
1915  Kokkos::create_mirror_view(sendBuffer);
1916  Kokkos::deep_copy(hostSendBuffer, sendBuffer);
1917  for (Ordinal i=0; i<count; ++i)
1918  localSendBuffer[i] = hostSendBuffer(i);
1919 
1920  // Copy receive buffer into local array (necessary to initialize Fad types
1921  // properly)
1922  Teuchos::Array<recv_value_type> localRecvBuffer(count);
1923  typename RecvViewType::HostMirror hostRecvBuffer =
1924  Kokkos::create_mirror_view(recvBuffer);
1925  Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
1926  for (Ordinal i=0; i<count; ++i)
1927  localRecvBuffer[i] = hostRecvBuffer(i);
1928 
1929  // Do reduce-all
1930  reduceAll(comm, serializer, reductType, count,
1931  localSendBuffer.getRawPtr(),
1932  localRecvBuffer.getRawPtr());
1933 
1934  // Copy back into original buffer
1935  for (Ordinal i=0; i<count; ++i)
1936  hostRecvBuffer(i) = localRecvBuffer[i];
1937  Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
1938 }
1939 
1940 
1941 template<typename Ordinal, class D, class ... P >
1942 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
1943 broadcast
1944  ( const Comm<Ordinal>& comm,
1945  const int rootRank ,
1946  const Ordinal count,
1947  const Kokkos::View<D,P...>& buffer)
1948 {
1949  typedef Kokkos::View<D,P...> view_type;
1950  typename view_type::array_type array_buffer = buffer;
1951  Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
1952  broadcast( comm, rootRank, array_count, array_buffer );
1953 }
1954 
1955 template<typename Ordinal,
1956  typename Serializer ,
1957  class D, class ... P >
1958 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
1959 broadcast
1960  ( const Comm<Ordinal>& comm,
1961  const Serializer& serializer,
1962  const int rootRank ,
1963  const Ordinal count,
1964  const Kokkos::View<D,P...>& buffer)
1965 {
1966  typedef Kokkos::View<D,P...> view_type;
1967  typename view_type::array_type array_buffer = buffer;
1968  Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
1969  broadcast( comm, *(serializer.getValueSerializer()), rootRank,
1970  array_count, array_buffer );
1971 }
1972 
1973 } // namespace Teuchos
1974 
1975 #endif
1976 
1977 //----------------------------------------------------------------------------
1978 
1979 #endif // defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
1980 
1981 #endif // defined(HAVE_SACADO_KOKKOSCORE)
1982 
1984 
1985 #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP */
int Ordinal
View
#define KOKKOS_FORCEINLINE_FUNCTION
#define KOKKOS_DEFAULTED_FUNCTION
#define KOKKOS_INLINE_FUNCTION
expr expr expr bar false
#define T
Definition: Sacado_rad.hpp:573
#define D
Definition: Sacado_rad.hpp:577
const int fad_dim
GeneralFad< DynamicStorage< T > > DFad
GeneralFad< StaticFixedStorage< T, Num > > SFad
GeneralFad< StaticStorage< T, Num > > SLFad
Base template specification for whether a type is a Fad type.
Base template specification for testing whether type is statically sized.
Base template specification for Promote.
Base template specification for ScalarType.
Base template specification for static size.
Get view type for any Fad type.