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