Sacado Package Browser (Single Doxygen Collection)  Version of the Day
KokkosExp_View_Fad.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 #ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP
31 #define KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP
32 
33 #include "Sacado_ConfigDefs.h"
34 #if defined(HAVE_SACADO_KOKKOSCORE)
35 
36 #include "Kokkos_Core.hpp"
37 #include "Kokkos_Macros.hpp"
38 
39 // Some definition that should exist whether the specializations exist or not
40 
41 namespace Kokkos {
42 
43 // Whether a given type is a view with Sacado FAD scalar type
44 template <typename view_type>
45 struct is_view_fad { static const bool value = false; };
46 
47 // Template function for extracting sacado dimension
48 template <typename view_type>
50 constexpr unsigned
51 dimension_scalar(const view_type& view) {
52  return 0;
53 }
54 
55 }
56 
57 // Make sure the user really wants these View specializations
58 #if defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
59 
60 #include "Sacado_Traits.hpp"
61 #include "impl/KokkosExp_ViewMapping.hpp"
63 
64 #define SACADO_SUPPORT_RANK_8 0
65 
66 //----------------------------------------------------------------------------
67 
68 namespace Kokkos {
69 namespace Experimental {
70 namespace Impl {
71 
72 struct ViewSpecializeSacadoFad {};
73 
74 template< class ... Args >
75 struct is_ViewSpecializeSacadoFad { enum { value = false }; };
76 
77 template< class D , class ... P , class ... Args >
78 struct is_ViewSpecializeSacadoFad< Kokkos::View<D,P...> , Args... > {
79  enum { value =
80  std::is_same< typename Kokkos::ViewTraits<D,P...>::specialize
81  , ViewSpecializeSacadoFad >::value
82  &&
83  ( ( sizeof...(Args) == 0 ) ||
84  is_ViewSpecializeSacadoFad< Args... >::value ) };
85 };
86 
87 } // namespace Impl
88 } // namespace Experimental
89 } // namespace Kokkos
90 
91 namespace Kokkos {
92 
93 template <typename T, typename ... P>
94 struct is_view_fad< View<T,P...> > {
95  typedef View<T,P...> view_type;
96  static const bool value =
97  std::is_same< typename view_type::specialize,
98  Experimental::Impl::ViewSpecializeSacadoFad >::value;
99 };
100 
101 template <typename T, typename ... P>
103 constexpr typename
104 std::enable_if< is_view_fad< View<T,P...> >::value, unsigned >::type
105 dimension_scalar(const View<T,P...>& view) {
106  return view.implementation_map().dimension_scalar();
107 }
108 
109 template <typename ViewType, typename Enabled = void>
110 struct ContiguousArrayType {
111  typedef ViewType type;
112 };
113 
114 template <typename D, typename ... P>
115 struct ContiguousArrayType< View<D,P...>,
116  typename std::enable_if< is_view_fad< View<D,P...> >::value >::type > {
117  typedef View<D,P...> view_type;
118  typedef typename view_type::data_type data_type;
119  typedef typename view_type::array_layout layout;
120  typedef typename view_type::device_type device;
121  typedef typename view_type::memory_traits memory;
122  typedef View<data_type,LayoutContiguous<layout>,device,memory> type;
123 };
124 
125 // Overload of deep_copy for Fad views intializing to a constant scalar
126 template< class DT, class ... DP >
127 void deep_copy(
128  const View<DT,DP...> & view ,
129  const typename Sacado::ScalarType< typename View<DT,DP...>::value_type >::type & value
130  , typename std::enable_if<(
131  std::is_same< typename ViewTraits<DT,DP...>::specialize
132  , Kokkos::Experimental::Impl::ViewSpecializeSacadoFad >::value
133  )>::type * = 0 )
134 {
135  static_assert(
136  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
137  typename ViewTraits<DT,DP...>::non_const_value_type >::value
138  , "Can only deep copy into non-const type" );
139 
140  Kokkos::Experimental::Impl::ViewFill< View<DT,DP...> >( view , value );
141 }
142 
143 // Overload of deep_copy for Fad views intializing to a constant Fad
144 template< class DT, class ... DP >
145 void deep_copy(
146  const View<DT,DP...> & view ,
147  const typename View<DT,DP...>::value_type & value
148  , typename std::enable_if<(
149  std::is_same< typename ViewTraits<DT,DP...>::specialize
150  , Kokkos::Experimental::Impl::ViewSpecializeSacadoFad >::value
151  )>::type * = 0 )
152 {
153  static_assert(
154  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
155  typename ViewTraits<DT,DP...>::non_const_value_type >::value
156  , "Can only deep copy into non-const type" );
157 
158  Kokkos::Experimental::Impl::ViewFill< View<DT,DP...> >( view , value );
159 }
160 
161 /* Specialize for deep copy of FAD */
162 template< class DT , class ... DP , class ST , class ... SP >
163 inline
164 void deep_copy( const View<DT,DP...> & dst ,
165  const View<ST,SP...> & src
166  , typename std::enable_if<(
167  std::is_same< typename ViewTraits<DT,DP...>::specialize
168  , Kokkos::Experimental::Impl::ViewSpecializeSacadoFad >::value
169  &&
170  std::is_same< typename ViewTraits<ST,SP...>::specialize
171  , Kokkos::Experimental::Impl::ViewSpecializeSacadoFad >::value
172  )>::type * = 0 )
173 {
174  static_assert(
175  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
176  typename ViewTraits<DT,DP...>::non_const_value_type >::value
177  , "Deep copy destination must be non-const" );
178 
179  static_assert(
180  ( unsigned(ViewTraits<DT,DP...>::rank) ==
181  unsigned(ViewTraits<ST,SP...>::rank) )
182  , "Deep copy destination and source must have same rank" );
183 
184  typedef typename View<DT,DP...>::array_type dst_array_type;
185  typedef typename View<ST,SP...>::array_type src_array_type;
186  Kokkos::deep_copy(
187  typename ContiguousArrayType< dst_array_type >::type( dst ) ,
188  typename ContiguousArrayType< src_array_type >::type( src ) );
189 }
190 
191 } // namespace Kokkos
192 
193 //----------------------------------------------------------------------------
194 
195 namespace Kokkos {
196 namespace Experimental {
197 namespace Impl {
198 
199 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
200 struct FadViewDataAnalysis
201 {
202 private:
203 
204  typedef ViewArrayAnalysis< DataType > array_analysis ;
205 
206 public:
207 
208  // Specialized view data mapping:
209  typedef ViewSpecializeSacadoFad specialize ;
210 
211  typedef typename array_analysis::dimension dimension ;
212  typedef typename array_analysis::value_type value_type ;
213  typedef typename array_analysis::const_value_type const_value_type ;
214  typedef typename array_analysis::non_const_value_type non_const_value_type ;
215 
216  // Generate analogous multidimensional array specification type.
217  typedef typename
218  ViewDataType< value_type , dimension >::type type ;
219  typedef typename
220  ViewDataType< const_value_type , dimension >::type const_type ;
221  typedef typename
222  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
223 
224 private:
225 
226  // A const ?
227  enum { is_const = std::is_same< value_type , const_value_type >::value };
228 
229  // The unwrapped scalar types:
230  typedef typename
231  std::conditional< is_const , const ScalarType , ScalarType >::type
232  scalar_type ;
233 
234  typedef ScalarType non_const_scalar_type ;
235  typedef const ScalarType const_scalar_type ;
236 
237 #if SACADO_SUPPORT_RANK_8
238 
239  // Append the FAD static dimension
240  // This is a hack for rank-8 dynamic view
241  typedef typename
242  std::conditional<
243  unsigned(array_analysis::dimension::rank) == 8 ,
244  typename array_analysis::dimension,
245  typename array_analysis::dimension::
246  template append<( DimFad ? DimFad + 1 : 0 )>::type >::type
247  scalar_dimension ;
248 
249 #else
250 
251  // Append the FAD static dimension
252  typedef typename array_analysis::dimension::
253  template append<( DimFad ? DimFad + 1 : 0 )>::type
254  scalar_dimension ;
255 
256 #endif
257 
258 public:
259 
260  // Generate "flattened" multidimensional array specification type.
261  typedef typename
262  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
263 
264  typedef typename
265  ViewDataType< const_scalar_type , scalar_dimension >::type
266  const_scalar_array_type ;
267 
268  typedef typename
269  ViewDataType< non_const_scalar_type , scalar_dimension >::type
270  non_const_scalar_array_type ;
271 };
272 
273 // Specialization for LayoutContiguous, where we don't allow striding within
274 // the FadType.
275 //
276 // Currently this is implemented by choosing the default ViewMapping
277 // specialization. In the future we will provide our own.
278 template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
279 struct FadViewDataAnalysis<DataType, LayoutContiguous<ArrayLayout>, ScalarType, DimFad>
280 {
281 private:
282 
283  typedef ViewArrayAnalysis< DataType > array_analysis ;
284 
285 public:
286 
287  // For now use the default mapping
288  typedef void specialize ;
289 
290  typedef typename array_analysis::dimension dimension ;
291  typedef typename array_analysis::value_type value_type ;
292  typedef typename array_analysis::const_value_type const_value_type ;
293  typedef typename array_analysis::non_const_value_type non_const_value_type ;
294 
295  // Generate analogous multidimensional array specification type.
296  typedef typename
297  ViewDataType< value_type , dimension >::type type ;
298  typedef typename
299  ViewDataType< const_value_type , dimension >::type const_type ;
300  typedef typename
301  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
302 
303  // Generate "flattened" multidimensional array specification type.
304  typedef type scalar_array_type ;
305  typedef const_type const_scalar_array_type ;
306  typedef non_const_type non_const_scalar_array_type ;
307 };
308 
309 } // namespace Impl
310 } // namespace Experimental
311 } // namespace Kokkos
312 
313 //----------------------------------------------------------------------------
314 
315 namespace Sacado {
316 namespace Fad { template< typename > class DFad ; }
317 namespace CacheFad { template< typename > class DFad ; }
318 namespace ELRFad { template< typename > class DFad ; }
319 namespace ELRCacheFad { template< typename > class DFad ; }
320 
321 namespace Fad { template< typename , int > class SFad ; }
322 namespace CacheFad { template< typename , int > class SFad ; }
323 namespace ELRFad { template< typename , int > class SFad ; }
324 namespace ELRCacheFad { template< typename , int > class SFad ; }
325 
326 namespace Fad { template< typename , int > class SLFad ; }
327 namespace CacheFad { template< typename , int > class SLFad ; }
328 namespace ELRFad { template< typename , int > class SLFad ; }
329 namespace ELRCacheFad { template< typename , int > class SLFad ; }
330 }
331 
332 namespace Kokkos {
333 namespace Experimental {
334 namespace Impl {
335 
336 #define KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( NS ) \
337 template< class DataType , class ArrayLayout , typename ScalarType > \
338 struct ViewDataAnalysis \
339  < DataType /* Original view data type */ \
340  , ArrayLayout \
341  , Sacado:: NS ::DFad< ScalarType > \
342  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , 0 > {}; \
343 \
344 template< class DataType , class ArrayLayout , typename ScalarType , int N > \
345 struct ViewDataAnalysis \
346  < DataType /* Original view data type */ \
347  , ArrayLayout \
348  , Sacado:: NS ::SFad< ScalarType , N > \
349  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
350  int(Sacado::StaticSize< Sacado:: NS ::SFad< ScalarType , N > >::value) \
351  > {}; \
352 \
353 template< class DataType , class ArrayLayout , typename ScalarType , int N > \
354 struct ViewDataAnalysis \
355  < DataType /* Original view data type */ \
356  , ArrayLayout \
357  , Sacado:: NS ::SLFad< ScalarType , N > \
358  > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
359  int(Sacado::StaticSize< Sacado:: NS ::SLFad< ScalarType , N > >::value) \
360  > {}; \
361 
362 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( Fad )
363 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( CacheFad )
364 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRFad )
365 KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRCacheFad )
366 
367 #undef KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD
368 
369 } // namespace Impl
370 } // namespace Experimental
371 } // namespace Kokkos
372 
373 //----------------------------------------------------------------------------
374 
375 namespace Kokkos {
376 namespace Experimental {
377 namespace Impl {
378 
379 template< class Traits >
380 class ViewMapping< Traits , /* View internal mapping */
381  typename std::enable_if<
382  ( std::is_same< typename Traits::specialize
383  , ViewSpecializeSacadoFad >::value
384  &&
385  ( std::is_same< typename Traits::array_layout
386  , Kokkos::LayoutLeft >::value
387  ||
388  std::is_same< typename Traits::array_layout
389  , Kokkos::LayoutRight >::value
390  ||
391  std::is_same< typename Traits::array_layout
392  , Kokkos::LayoutStride >::value
393  )
394  )>::type >
395 {
396 private:
397 
398  template< class , class ... > friend class ViewMapping ;
399  template< class , class ... > friend class Kokkos::Experimental::View ;
400 
401  typedef typename Traits::value_type fad_type ;
402  typedef typename Sacado::ValueType< fad_type >::type fad_value_type ;
403  typedef typename
404  std::add_const< fad_value_type >::type const_fad_value_type ;
405 
406  enum { FadStaticDimension = Sacado::StaticSize< fad_type >::value };
408 
409  // Only LayoutRight has a static stride one
410  enum { FadStaticStride =
411  std::is_same< typename Traits::array_layout
412  , Kokkos::LayoutRight >::value ? 1 : 0 };
413 
415 
416  typedef fad_value_type * handle_type ;
417 
418  typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
419 
420 #if SACADO_SUPPORT_RANK_8
421 
422  // Append the fad dimension for the internal offset mapping.
423  // This is a hack for rank-8 dynamic view
424  typedef ViewOffset
425  < typename std::conditional<
426  unsigned(array_analysis::dimension::rank) == 8,
427  typename array_analysis::dimension,
428  typename array_analysis::dimension::
429  template append<( FadStaticDimension ? FadStaticDimension + 1 : 0 )>::type >::type
430  , typename Traits::array_layout
431  , void
432  > offset_type ;
433 
434 #else
435 
436  // Append the fad dimension for the internal offset mapping.
437  typedef ViewOffset
438  < typename array_analysis::dimension::
439  template append<( FadStaticDimension ? FadStaticDimension + 1 : 0 )>::type
440  , typename Traits::array_layout
441  , void
442  > offset_type ;
443 
444 #endif
445 
446  handle_type m_handle ;
447  offset_type m_offset ;
448  sacado_size_type m_fad_size ;
449  sacado_stride_type m_fad_stride ;
450 
451 public:
452 
453  //----------------------------------------
454  // Domain dimensions
455 
456  enum { Rank = Traits::dimension::rank };
457 
458  // Using the internal offset mapping so limit to public rank:
459  template< typename iType >
460  KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
461  { return unsigned(r) < unsigned(Rank) ? m_offset.m_dim.extent(r) : 1 ; }
462 
463  KOKKOS_INLINE_FUNCTION constexpr
464  typename Traits::array_layout layout() const
465  { return typename Traits::array_layout(
466  0 < unsigned(Rank) ? m_offset.dimension_0() : 0,
467  1 < unsigned(Rank) ? m_offset.dimension_1() : 0,
468  2 < unsigned(Rank) ? m_offset.dimension_2() : 0,
469  3 < unsigned(Rank) ? m_offset.dimension_3() : 0,
470  4 < unsigned(Rank) ? m_offset.dimension_4() : 0,
471  5 < unsigned(Rank) ? m_offset.dimension_5() : 0,
472  6 < unsigned(Rank) ? m_offset.dimension_6() : 0,
473  7 < unsigned(Rank) ? m_offset.dimension_7() : 0
474  );
475  }
476 
477  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
478  { return 0 < unsigned(Rank) ? m_offset.dimension_0() : 1 ; }
479 
480  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
481  { return 1 < unsigned(Rank) ? m_offset.dimension_1() : 1 ; }
482 
483  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
484  { return 2 < unsigned(Rank) ? m_offset.dimension_2() : 1 ; }
485 
486  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
487  { return 3 < unsigned(Rank) ? m_offset.dimension_3() : 1 ; }
488 
489  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
490  { return 4 < unsigned(Rank) ? m_offset.dimension_4() : 1 ; }
491 
492  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
493  { return 5 < unsigned(Rank) ? m_offset.dimension_5() : 1 ; }
494 
495  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
496  { return 6 < unsigned(Rank) ? m_offset.dimension_6() : 1 ; }
497 
498  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
499  { return 7 < unsigned(Rank) ? m_offset.dimension_7() : 1 ; }
500 
501  // Can only be regular layout with uniform striding
502  // when LayoutRight with contiguous values so not guaranteed true.
503  using is_regular = std::false_type ;
504 
505  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const { return 0 ; }
506  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const { return 0 ; }
507  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const { return 0 ; }
508  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const { return 0 ; }
509  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const { return 0 ; }
510  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const { return 0 ; }
511  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const { return 0 ; }
512  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const { return 0 ; }
513 
514  // Size of sacado scalar dimension
515  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
516  { return m_fad_size.value+1; }
517 
518  //----------------------------------------
519  // Range of mapping
520 
521  // Return type of reference operators
522  typedef typename
524 
526  typedef fad_value_type * pointer_type ;
527 
529  KOKKOS_INLINE_FUNCTION constexpr size_t span() const
530  { return m_offset.span(); }
531 
533  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
534  { return false ; }
535 
537  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
538  { return m_handle ; }
539 
540  //----------------------------------------
541 
543  reference_type reference() const
544  { return reference_type( m_handle
545  , m_fad_size.value
546  , m_fad_stride.value ); }
547 
548  template< typename I0 >
550  reference_type
551  reference( const I0 & i0 ) const
552  { return reference_type( m_handle + m_offset(i0,0)
553  , m_fad_size.value
554  , m_fad_stride.value ); }
555 
556  template< typename I0 , typename I1 >
558  reference_type reference( const I0 & i0 , const I1 & i1 ) const
559  { return reference_type( m_handle + m_offset(i0,i1,0)
560  , m_fad_size.value
561  , m_fad_stride.value ); }
562 
563 
564  template< typename I0 , typename I1 , typename I2 >
566  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
567  { return reference_type( m_handle + m_offset(i0,i1,i2,0)
568  , m_fad_size.value
569  , m_fad_stride.value ); }
570 
571  template< typename I0 , typename I1 , typename I2 , typename I3 >
573  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
574  { return reference_type( m_handle + m_offset(i0,i1,i2,i3,0)
575  , m_fad_size.value
576  , m_fad_stride.value ); }
577 
578  template< typename I0 , typename I1 , typename I2 , typename I3
579  , typename I4 >
581  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
582  , const I4 & i4 ) const
583  { return reference_type( m_handle + m_offset(i0,i1,i2,i3,i4,0)
584  , m_fad_size.value
585  , m_fad_stride.value ); }
586 
587  template< typename I0 , typename I1 , typename I2 , typename I3
588  , typename I4 , typename I5 >
590  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
591  , const I4 & i4 , const I5 & i5 ) const
592  { return reference_type( m_handle + m_offset(i0,i1,i2,i3,i4,i5,0)
593  , m_fad_size.value
594  , m_fad_stride.value ); }
595 
596 
597  template< typename I0 , typename I1 , typename I2 , typename I3
598  , typename I4 , typename I5 , typename I6 >
600  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
601  , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
602  { return reference_type( m_handle + m_offset(i0,i1,i2,i3,i4,i5,i6,0)
603  , m_fad_size.value
604  , m_fad_stride.value ); }
605 
606 #if SACADO_SUPPORT_RANK_8
607 
608  // This is a hack for rank-8 dynamic view
609  template< typename I0 , typename I1 , typename I2 , typename I3
610  , typename I4 , typename I5 , typename I6 , typename I7>
612  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
613  , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7 ) const
614  { return reference_type( m_handle + m_offset(i0,i1,i2,i3,i4,i5,i6,0)
615  , m_fad_size.value
616  , m_fad_stride.value ); }
617 
618 #endif
619 
620  //----------------------------------------
621 
624  static constexpr size_t memory_span( typename Traits::array_layout const & layout )
625  {
626  // Do not introduce padding...
627  typedef std::integral_constant< unsigned , 0 > padding ;
628  return offset_type( padding() , layout ).span() * sizeof(fad_value_type);
629  }
630 
631  //----------------------------------------
632 
633  KOKKOS_INLINE_FUNCTION ~ViewMapping() = default ;
634  KOKKOS_INLINE_FUNCTION ViewMapping() : m_handle(0) , m_offset() , m_fad_size(0) , m_fad_stride(0) {}
635 
636  KOKKOS_INLINE_FUNCTION ViewMapping( const ViewMapping & ) = default ;
637  KOKKOS_INLINE_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
638 
639  KOKKOS_INLINE_FUNCTION ViewMapping( ViewMapping && ) = default ;
640  KOKKOS_INLINE_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
641 
642  template< class ... P >
644  ViewMapping
645  ( ViewCtorProp< P ... > const & prop
646  , typename Traits::array_layout const & local_layout
647  )
648  : m_handle( ( (ViewCtorProp<void,pointer_type> const &) prop ).value )
649  , m_offset( std::integral_constant< unsigned , 0 >()
650  , local_layout )
651  // Query m_offset, not input, in case of static dimension
652  , m_fad_size(
653  ( Rank == 0 ? m_offset.dimension_0() :
654  ( Rank == 1 ? m_offset.dimension_1() :
655  ( Rank == 2 ? m_offset.dimension_2() :
656  ( Rank == 3 ? m_offset.dimension_3() :
657  ( Rank == 4 ? m_offset.dimension_4() :
658  ( Rank == 5 ? m_offset.dimension_5() :
659  ( Rank == 6 ? m_offset.dimension_6() :
660  m_offset.dimension_7() ))))))) - 1 )
661  , m_fad_stride(
662  ( Rank == 0 ? m_offset.stride_0() :
663  ( Rank == 1 ? m_offset.stride_1() :
664  ( Rank == 2 ? m_offset.stride_2() :
665  ( Rank == 3 ? m_offset.stride_3() :
666  ( Rank == 4 ? m_offset.stride_4() :
667  ( Rank == 5 ? m_offset.stride_5() :
668  ( Rank == 6 ? m_offset.stride_6() :
669  m_offset.stride_7() ))))))))
670 
671  {
672  const unsigned fad_dim =
673  ( Rank == 0 ? m_offset.dimension_0() :
674  ( Rank == 1 ? m_offset.dimension_1() :
675  ( Rank == 2 ? m_offset.dimension_2() :
676  ( Rank == 3 ? m_offset.dimension_3() :
677  ( Rank == 4 ? m_offset.dimension_4() :
678  ( Rank == 5 ? m_offset.dimension_5() :
679  ( Rank == 6 ? m_offset.dimension_6() :
680  m_offset.dimension_7() )))))));
681  if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
682  Kokkos::abort("invalid fad dimension (0) supplied!");
683  }
684 
685  //----------------------------------------
686  /* Allocate and construct mapped array.
687  * Allocate via shared allocation record and
688  * return that record for allocation tracking.
689  */
690  template< class ... P >
691  SharedAllocationRecord<> *
692  allocate_shared( ViewCtorProp< P... > const & prop
693  , typename Traits::array_layout const & local_layout )
694  {
695  typedef ViewCtorProp< P... > ctor_prop ;
696 
697  typedef typename ctor_prop::execution_space execution_space ;
698  typedef typename Traits::memory_space memory_space ;
699  typedef ViewValueFunctor< execution_space , fad_value_type > functor_type ;
700  typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
701 
702  // Disallow padding
703  typedef std::integral_constant< unsigned , 0 > padding ;
704 
705  m_offset = offset_type( padding(), local_layout );
706  const unsigned fad_dim =
707  ( Rank == 0 ? m_offset.dimension_0() :
708  ( Rank == 1 ? m_offset.dimension_1() :
709  ( Rank == 2 ? m_offset.dimension_2() :
710  ( Rank == 3 ? m_offset.dimension_3() :
711  ( Rank == 4 ? m_offset.dimension_4() :
712  ( Rank == 5 ? m_offset.dimension_5() :
713  ( Rank == 6 ? m_offset.dimension_6() :
714  m_offset.dimension_7() )))))));
715  if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
716  Kokkos::abort("invalid fad dimension (0) supplied!");
717  m_fad_size = fad_dim - 1 ;
718 
719  m_fad_stride =
720  ( Rank == 0 ? m_offset.stride_0() :
721  ( Rank == 1 ? m_offset.stride_1() :
722  ( Rank == 2 ? m_offset.stride_2() :
723  ( Rank == 3 ? m_offset.stride_3() :
724  ( Rank == 4 ? m_offset.stride_4() :
725  ( Rank == 5 ? m_offset.stride_5() :
726  ( Rank == 6 ? m_offset.stride_6() :
727  m_offset.stride_7() )))))));
728 
729  const size_t alloc_size = m_offset.span() * sizeof(fad_value_type);
730 
731  // Create shared memory tracking record with allocate memory from the memory space
732  record_type * const record =
733  record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
734  , ( (ViewCtorProp<void,std::string> const &) prop ).value
735  , alloc_size );
736 
737  // Only set the the pointer and initialize if the allocation is non-zero.
738  // May be zero if one of the dimensions is zero.
739  if ( alloc_size ) {
740 
741  m_handle = handle_type( reinterpret_cast< pointer_type >( record->data() ) );
742 
743  if ( ctor_prop::initialize ) {
744  // Assume destruction is only required when construction is requested.
745  // The ViewValueFunctor has both value construction and destruction operators.
746  record->m_destroy = functor_type( ( (ViewCtorProp<void,execution_space> const &) prop).value
747  , (fad_value_type *) m_handle
748  , m_offset.span()
749  );
750 
751  // Construct values
752  record->m_destroy.construct_shared_allocation();
753  }
754  }
755 
756  return record ;
757  }
758 
759 };
760 
761 } // namespace Impl
762 } // namespace Experimental
763 } // namespace Kokkos
764 
765 //----------------------------------------------------------------------------
766 
767 namespace Kokkos {
768 namespace Experimental {
769 namespace Impl {
770 
777 template< class DstTraits , class SrcTraits >
778 class ViewMapping< DstTraits , SrcTraits ,
779  typename std::enable_if<(
780  std::is_same< typename DstTraits::memory_space
781  , typename SrcTraits::memory_space >::value
782  &&
783  // Destination view has FAD or ordinary
784  ( std::is_same< typename DstTraits::specialize
785  , ViewSpecializeSacadoFad >::value
786  ||
787  std::is_same< typename DstTraits::specialize , void >::value
788  )
789  &&
790  // Source view has FAD only
791  std::is_same< typename SrcTraits::specialize
792  , ViewSpecializeSacadoFad >::value
793  )>::type >
794 {
795 public:
796 
797  enum { is_assignable = true };
798 
799  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
800  typedef ViewMapping< DstTraits , void > DstType ;
801  typedef ViewMapping< SrcTraits , void > SrcFadType ;
802 
803  template< class S , class D >
805  typename std::enable_if<(
806  std::is_same< S , ViewSpecializeSacadoFad >::value
807  )>::type
808  assign_fad_size( D & dst , const SrcFadType & src )
809  { dst.m_fad_size = src.m_fad_size.value ;
810  dst.m_fad_stride = src.m_fad_stride.value ;
811  }
812 
813  template< class S , class D >
815  typename std::enable_if<(
816  ! std::is_same< S , ViewSpecializeSacadoFad >::value
817  )>::type
818  assign_fad_size( D & , const SrcFadType & ) {}
819 
820  template< class DstType >
822  void assign( DstType & dst
823  , const SrcFadType & src
824  , const TrackType & )
825  {
826  static_assert(
827  (
828  std::is_same< typename DstTraits::array_layout
829  , Kokkos::LayoutLeft >::value ||
830  std::is_same< typename DstTraits::array_layout
831  , Kokkos::LayoutRight >::value ||
832  std::is_same< typename DstTraits::array_layout
833  , Kokkos::LayoutStride >::value
834  )
835  &&
836  (
837  std::is_same< typename SrcTraits::array_layout
838  , Kokkos::LayoutLeft >::value ||
839  std::is_same< typename SrcTraits::array_layout
840  , Kokkos::LayoutRight >::value ||
841  std::is_same< typename SrcTraits::array_layout
842  , Kokkos::LayoutStride >::value
843  )
844  , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
845 
846  static_assert(
847  std::is_same< typename DstTraits::array_layout
848  , typename SrcTraits::array_layout >::value ||
849  std::is_same< typename DstTraits::array_layout
850  , Kokkos::LayoutStride >::value ,
851  "View assignment must have compatible layout" );
852 
853  static_assert(
854  std::is_same< typename DstTraits::scalar_array_type
855  , typename SrcTraits::scalar_array_type >::value ||
856  std::is_same< typename DstTraits::scalar_array_type
857  , typename SrcTraits::const_scalar_array_type >::value ,
858  "View assignment must have same value type or const = non-const" );
859 
860  static_assert(
861  ViewDimensionAssignable
862  < typename DstType::offset_type::dimension_type
863  , typename SrcFadType::offset_type::dimension_type >::value ,
864  "View assignment must have compatible dimensions" );
865 
866  typedef typename DstType::offset_type dst_offset_type ;
867 
868  dst.m_offset = dst_offset_type( src.m_offset );
869  dst.m_handle = src.m_handle ;
870 
871  ViewMapping::template assign_fad_size< typename DstTraits::specialize >( dst , src );
872  }
873 };
874 
875 } // namespace Impl
876 } // namespace Experimental
877 } // namespace Kokkos
878 
879 //----------------------------------------------------------------------------
880 
881 namespace Kokkos {
882 namespace Experimental {
883 namespace Impl {
884 
885 // Subview mapping
886 
887 template< class SrcTraits , class ... Args >
888 struct ViewMapping
889  < typename std::enable_if<(
890  // Source view has FAD only
891  std::is_same< typename SrcTraits::specialize
892  , ViewSpecializeSacadoFad >::value
893  &&
894  (
895  std::is_same< typename SrcTraits::array_layout
896  , Kokkos::LayoutLeft >::value ||
897  std::is_same< typename SrcTraits::array_layout
898  , Kokkos::LayoutRight >::value ||
899  std::is_same< typename SrcTraits::array_layout
900  , Kokkos::LayoutStride >::value
901  )
902  )>::type
903  , SrcTraits
904  , Args ... >
905 {
906 private:
907 
908  static_assert( SrcTraits::rank == sizeof...(Args) , "" );
909 
910  enum
911  { RZ = false
912  , R0 = bool(is_integral_extent<0,Args...>::value)
913  , R1 = bool(is_integral_extent<1,Args...>::value)
914  , R2 = bool(is_integral_extent<2,Args...>::value)
915  , R3 = bool(is_integral_extent<3,Args...>::value)
916  , R4 = bool(is_integral_extent<4,Args...>::value)
917  , R5 = bool(is_integral_extent<5,Args...>::value)
918  , R6 = bool(is_integral_extent<6,Args...>::value)
919  };
920 
921  // Public rank
922  enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
923  + unsigned(R4) + unsigned(R5) + unsigned(R6) };
924 
925  // Whether right-most non-FAD rank is a range.
926  enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
927  1 == SrcTraits::rank ? R0 : (
928  2 == SrcTraits::rank ? R1 : (
929  3 == SrcTraits::rank ? R2 : (
930  4 == SrcTraits::rank ? R3 : (
931  5 == SrcTraits::rank ? R4 : (
932  6 == SrcTraits::rank ? R5 : R6 ))))))) };
933 
934  // Subview's layout
935  // If LayoutRight then FAD is contiguous
936  // For LayoutLeft, result is LayoutLeft only if 1st arg is a range,
937  // and since last (FAD) dimension is also a range, and these
938  // ranges must be consecutive, the input rank must be 1
939  typedef typename std::conditional<
940  ( /* Same layout IF */
941  ( rank == 0 )
942  ||
943  ( std::is_same< typename SrcTraits::array_layout
944  , Kokkos::LayoutRight >::value
945  &&
946  ( rank == 1 ) && R0_rev
947  )
948  ||
949  ( std::is_same< typename SrcTraits::array_layout
950  , Kokkos::LayoutLeft >::value
951  &&
952  ( rank == 1 ) && (SrcTraits::rank == 1) && R0
953  )
954  ), typename SrcTraits::array_layout , Kokkos::LayoutStride
955  >::type array_layout ;
956 
957  typedef typename SrcTraits::value_type fad_type ;
958 
959  typedef typename std::conditional< rank == 0 , fad_type ,
960  typename std::conditional< rank == 1 , fad_type * ,
961  typename std::conditional< rank == 2 , fad_type ** ,
962  typename std::conditional< rank == 3 , fad_type *** ,
963  typename std::conditional< rank == 4 , fad_type **** ,
964  typename std::conditional< rank == 5 , fad_type ***** ,
965  typename std::conditional< rank == 6 , fad_type ****** ,
966  fad_type *******
967  >::type >::type >::type >::type >::type >::type >::type
968  data_type ;
969 
970 public:
971 
972  typedef Kokkos::Experimental::ViewTraits
973  < data_type
974  , array_layout
975  , typename SrcTraits::device_type
976  , typename SrcTraits::memory_traits > traits_type ;
977 
978  typedef Kokkos::Experimental::View
979  < data_type
980  , array_layout
981  , typename SrcTraits::device_type
982  , typename SrcTraits::memory_traits > type ;
983 
984 
986  static void assign( ViewMapping< traits_type , void > & dst
987  , ViewMapping< SrcTraits , void > const & src
988  , Args ... args )
989  {
990  typedef ViewMapping< traits_type , void > DstType ;
991  typedef typename DstType::offset_type dst_offset_type ;
992  typedef typename DstType::handle_type dst_handle_type ;
993 
994  const SubviewExtents< SrcTraits::rank + 1 , rank + 1 >
995  extents( src.m_offset.m_dim , args... , Kokkos::ALL() );
996 
997  dst.m_offset = dst_offset_type( src.m_offset , extents );
998  dst.m_handle = dst_handle_type( src.m_handle +
999  src.m_offset( extents.domain_offset(0)
1000  , extents.domain_offset(1)
1001  , extents.domain_offset(2)
1002  , extents.domain_offset(3)
1003  , extents.domain_offset(4)
1004  , extents.domain_offset(5)
1005  , extents.domain_offset(6)
1006  , extents.domain_offset(7)
1007  ) );
1008  dst.m_fad_size = src.m_fad_size;
1009  dst.m_fad_stride = src.m_fad_stride.value;
1010  }
1011 
1012 };
1013 
1014 } // namespace Impl
1015 } // namespace Experimental
1016 } // namespace Kokkos
1017 
1018 //----------------------------------------------------------------------------
1019 //----------------------------------------------------------------------------
1020 
1021 #if defined(HAVE_SACADO_KOKKOSCORE) && \
1022  defined(HAVE_SACADO_TEUCHOSKOKKOSCOMM) && \
1023  defined(HAVE_SACADO_VIEW_SPEC) && \
1024  ! defined(SACADO_DISABLE_FAD_VIEW_SPEC)
1025 
1026 #include "Kokkos_TeuchosCommAdapters.hpp"
1027 
1028 namespace Teuchos {
1029 
1030 template< typename Ordinal , class SD , class ... SP , class RD , class ... RP >
1031 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
1032  Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
1033  >::type
1034 reduceAll
1035  ( const Comm<Ordinal>& comm,
1036  const EReductionType reductType ,
1037  const Ordinal count,
1038  const Kokkos::View<SD,SP...> & sendBuffer ,
1039  const Kokkos::View<RD,RP...> & recvBuffer )
1040 {
1041  // We can't implement reduceAll by extracting the underlying array (since we
1042  // can't reduce across the derivative dimension) and we can't just extract
1043  // a pointer due to ViewFad. In principle we could handle ViewFad in the
1044  // serializer, but for the time being we just copy the view's into local
1045  // buffers (on the host).
1046  typedef Kokkos::View<SD,SP...> SendViewType;
1047  typedef Kokkos::View<RD,RP...> RecvViewType;
1048  typedef typename SendViewType::value_type send_value_type;
1049  typedef typename RecvViewType::value_type recv_value_type;
1050 
1052  SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
1053  "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
1054  "The send View's rank is " << SendViewType::rank << " and the receive "
1055  "View's rank is " << RecvViewType::rank << ".");
1056 
1057  // Copy send buffer into local array
1058  Teuchos::Array<send_value_type> localSendBuffer(count);
1059  typename SendViewType::HostMirror hostSendBuffer =
1060  Kokkos::create_mirror_view(sendBuffer);
1061  Kokkos::deep_copy(hostSendBuffer, sendBuffer);
1062  for (Ordinal i=0; i<count; ++i)
1063  localSendBuffer[i] = hostSendBuffer(i);
1064 
1065  // Copy receive buffer into local array (necessary to initialize Fad types
1066  // properly)
1067  Teuchos::Array<recv_value_type> localRecvBuffer(count);
1068  typename RecvViewType::HostMirror hostRecvBuffer =
1069  Kokkos::create_mirror_view(recvBuffer);
1070  Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
1071  for (Ordinal i=0; i<count; ++i)
1072  localRecvBuffer[i] = hostRecvBuffer(i);
1073 
1074  // Do reduce-all
1075  reduceAll(comm, reductType, count,
1076  localSendBuffer.getRawPtr(),
1077  localRecvBuffer.getRawPtr());
1078 
1079  // Copy back into original buffer
1080  for (Ordinal i=0; i<count; ++i)
1081  hostRecvBuffer(i) = localRecvBuffer[i];
1082  Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
1083 }
1084 
1085 
1086 template< typename Ordinal , typename Serializer ,
1087  class SD , class ... SP , class RD , class ... RP >
1088 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
1089  Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
1090  >::type
1091 reduceAll
1092  ( const Comm<Ordinal>& comm,
1093  const Serializer& serializer,
1094  const EReductionType reductType ,
1095  const Ordinal count,
1096  const Kokkos::View<SD,SP...> & sendBuffer ,
1097  const Kokkos::View<RD,RP...> & recvBuffer )
1098 {
1099  // We can't implement reduceAll by extracting the underlying array (since we
1100  // can't reduce across the derivative dimension) and we can't just extract
1101  // a pointer due to ViewFad. In principle we could handle ViewFad in the
1102  // serializer, but for the time being we just copy the view's into local
1103  // buffers (on the host).
1104  typedef Kokkos::View<SD,SP...> SendViewType;
1105  typedef Kokkos::View<RD,RP...> RecvViewType;
1106  typedef typename SendViewType::value_type send_value_type;
1107  typedef typename RecvViewType::value_type recv_value_type;
1108 
1110  SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
1111  "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
1112  "The send View's rank is " << SendViewType::rank << " and the receive " "View's rank is " << RecvViewType::rank << ".");
1113 
1114  // Copy send buffer into local array
1115  Teuchos::Array<send_value_type> localSendBuffer(count);
1116  typename SendViewType::HostMirror hostSendBuffer =
1117  Kokkos::create_mirror_view(sendBuffer);
1118  Kokkos::deep_copy(hostSendBuffer, sendBuffer);
1119  for (Ordinal i=0; i<count; ++i)
1120  localSendBuffer[i] = hostSendBuffer(i);
1121 
1122  // Copy receive buffer into local array (necessary to initialize Fad types
1123  // properly)
1124  Teuchos::Array<recv_value_type> localRecvBuffer(count);
1125  typename RecvViewType::HostMirror hostRecvBuffer =
1126  Kokkos::create_mirror_view(recvBuffer);
1127  Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
1128  for (Ordinal i=0; i<count; ++i)
1129  localRecvBuffer[i] = hostRecvBuffer(i);
1130 
1131  // Do reduce-all
1132  reduceAll(comm, serializer, reductType, count,
1133  localSendBuffer.getRawPtr(),
1134  localRecvBuffer.getRawPtr());
1135 
1136  // Copy back into original buffer
1137  for (Ordinal i=0; i<count; ++i)
1138  hostRecvBuffer(i) = localRecvBuffer[i];
1139  Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
1140 }
1141 
1142 
1143 template<typename Ordinal, class D, class ... P >
1144 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
1145 broadcast
1146  ( const Comm<Ordinal>& comm,
1147  const int rootRank ,
1148  const Ordinal count,
1149  const Kokkos::View<D,P...>& buffer)
1150 {
1151  typedef Kokkos::View<D,P...> view_type;
1152  typename view_type::array_type array_buffer = buffer;
1153  Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
1154  broadcast( comm, rootRank, array_count, array_buffer );
1155 }
1156 
1157 template<typename Ordinal,
1158  typename Serializer ,
1159  class D, class ... P >
1160 typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
1161 broadcast
1162  ( const Comm<Ordinal>& comm,
1163  const Serializer& serializer,
1164  const int rootRank ,
1165  const Ordinal count,
1166  const Kokkos::View<D,P...>& buffer)
1167 {
1168  typedef Kokkos::View<D,P...> view_type;
1169  typename view_type::array_type array_buffer = buffer;
1170  Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
1171  broadcast( comm, *(serializer.getValueSerializer()), rootRank,
1172  array_count, array_buffer );
1173 }
1174 
1175 } // namespace Teuchos
1176 
1177 #endif
1178 
1179 //----------------------------------------------------------------------------
1180 
1181 #endif // defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
1182 
1183 #endif // defined(HAVE_SACADO_KOKKOSCORE)
1184 
1185 #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP */
Base template specification for ScalarType.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Base template specification for static size.
#define KOKKOS_INLINE_FUNCTION
#define T
Definition: Sacado_rad.hpp:573
#define D
Definition: Sacado_rad.hpp:577
View
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
int Ordinal
expr expr expr bar false
#define KOKKOS_FORCEINLINE_FUNCTION
unsigned dimension_scalar(const View &v, const ViewPack &... views)
Get view type for any Fad type.