Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KokkosExp_View_Fad.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
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 
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 
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 */
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 KOKKOS_DEFAULTED_FUNCTION
#define D
Definition: Sacado_rad.hpp:577
GeneralFad< DynamicStorage< T > > DFad
int Ordinal
void
Definition: uninit.c:96
const int fad_dim
expr expr expr bar false
#define KOKKOS_FORCEINLINE_FUNCTION
GeneralFad< StaticFixedStorage< T, Num > > SFad
Base template specification for Promote.
if(first)
Definition: uninit.c:101
Base template specification for testing whether type is statically sized.
Get view type for any Fad type.