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