Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
KokkosExp_View_Fad.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Sacado Package
5// Copyright (2006) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// This library is free software; you can redistribute it and/or modify
11// it under the terms of the GNU Lesser General Public License as
12// published by the Free Software Foundation; either version 2.1 of the
13// License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23// USA
24// Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25// (etphipp@sandia.gov).
26//
27// ***********************************************************************
28// @HEADER
29
30#ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP
31#define KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP
32
33#include "Sacado_ConfigDefs.h"
34#if defined(HAVE_SACADO_KOKKOSCORE)
35
36// Only include forward declarations so any overloads appear before they
37// might be used inside Kokkos
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
53namespace Kokkos {
54
55// Whether a given type is a view with Sacado FAD scalar type
56template <typename view_type>
57struct 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
61template <typename view_type>
62struct is_view_fad_contiguous { static const bool value = false; };
63
64// Template function for extracting sacado dimension
65template <typename view_type>
66KOKKOS_INLINE_FUNCTION
67constexpr unsigned
68dimension_scalar(const view_type& /* view */) {
69 return 0;
70}
71
72// Template function for extracting aligned sacado dimension
73template <typename view_type>
74KOKKOS_INLINE_FUNCTION
75constexpr unsigned
76dimension_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
87namespace Kokkos {
88namespace Impl {
89
90struct ViewSpecializeSacadoFad {};
91struct ViewSpecializeSacadoFadContiguous {};
92
93template< class ... Args >
94struct is_ViewSpecializeSacadoFad { enum { value = false }; };
95
96template< class D , class ... P , class ... Args >
97struct 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
109namespace Kokkos {
110
111template <typename T, typename ... P>
112struct 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
121template <typename T, typename ... P>
122struct 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"
135
136namespace Kokkos {
137namespace 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
141template<class DT, class ... DP,
142 class ST, class ... SP>
143typename std::enable_if< is_view_fad< Kokkos::View<DT,DP...> >::value &&
144 is_view_fad< Kokkos::View<ST,SP...> >::value
145 >::type
146view_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
153template<class ExecutionSpace,
154 class DT, class ... DP,
155 class ST, class ... SP>
156typename std::enable_if< is_view_fad< Kokkos::View<DT,DP...> >::value &&
157 is_view_fad< Kokkos::View<ST,SP...> >::value
158 >::type
159view_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
170namespace Kokkos {
171
172template <typename T, typename ... P>
173KOKKOS_INLINE_FUNCTION
174constexpr typename
175std::enable_if< is_view_fad< View<T,P...> >::value, unsigned >::type
176dimension_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
184template <typename Layout>
185struct ApplyNatural {
186 typedef LayoutNatural<Layout> type;
187};
188
189template <typename Layout>
190struct ApplyNatural< LayoutNatural<Layout> > {
191 typedef LayoutNatural<Layout> type;
192};
193
194template < typename T, typename Enable = void >
195struct ArrayScalar;
196
197template < typename T >
198struct ArrayScalar< T, typename std::enable_if< !Sacado::IsFad<T>::value >::type > {
199 typedef T type;
200};
201
202template < typename T >
203struct 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
208template < typename DataType, int Rank >
209struct 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
215template < typename DataType >
216struct AppendRankToConvertedFad< DataType, 0 > {
217 typedef DataType type;
218};
219
220
221template < class ArrayLayout, class Enable = void >
222struct ViewArrayLayoutSelector;
223
224template < class ArrayLayout >
225struct ViewArrayLayoutSelector< ArrayLayout, typename std::enable_if< std::is_same<ArrayLayout, Kokkos::LayoutLeft>::value >::type >
226{
227 using type = Kokkos::LayoutLeft;
228};
229
230template < class ArrayLayout >
231struct ViewArrayLayoutSelector< ArrayLayout, typename std::enable_if< std::is_same<ArrayLayout, Kokkos::LayoutRight>::value >::type >
232{
233 using type = Kokkos::LayoutRight;
234};
235
236template < class ArrayLayout >
237struct ViewArrayLayoutSelector< ArrayLayout, typename std::enable_if< std::is_same<ArrayLayout, Kokkos::LayoutStride>::value >::type >
238{
239 using type = Kokkos::LayoutStride;
240};
241
242template < typename ViewType, typename Enable = void >
243struct PODViewDeepCopyType;
244
245template < typename ViewType >
246struct 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
262template < typename ViewType >
263struct PODViewDeepCopyType< ViewType, typename std::enable_if< !is_view_fad<ViewType>::value >::type >
264{
265 typedef ViewType type;
266};
267
268
269template <typename ViewType, typename Enabled = void>
270struct NaturalArrayType {
271 typedef ViewType type;
272};
273
274template <typename D, typename ... P>
275struct 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
287namespace Impl {
288
289template <class OutputView, typename Enabled = void>
290struct 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
330template< class DT, class ... DP >
331void 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
351template< class DT, class ... DP >
352void 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 */
371template< class ExecSpace, class DT , class ... DP , class ST , class ... SP >
372inline
373void 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 */
415template< class DT , class ... DP , class ST , class ... SP >
416inline
417void 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
439template< class T , class ... P >
440inline
441typename 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
449create_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
460template< class T , class ... P >
461inline
462typename 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
470create_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
501template<class Space, class T, class ... P, typename Enabled>
502typename 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
508create_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
516template< class T , class ... P >
517inline
518typename 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
526create_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
539template< class T , class ... P >
540inline
541typename 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
549create_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
582template<class Space, class T, class ... P, typename Enable>
583typename 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
589create_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
599template <class Space, class T, class... P>
600typename Impl::MirrorViewType<Space, T, P...>::view_type
601create_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
617template <class Space, class T, class... P>
618typename Impl::MirrorViewType<Space, T, P...>::view_type
619create_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
640namespace Impl {
641
642template <unsigned N, typename... Args>
643KOKKOS_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...>>
650as_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
656template <unsigned N, typename T, typename... Args>
657std::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...>>
665as_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//----------------------------------------------------------------------------
676
677namespace Kokkos {
678namespace Impl {
679
680template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
681struct FadViewDataAnalysis
682{
683private:
684
685 typedef ViewArrayAnalysis< DataType > array_analysis ;
686
687public:
688
689 // Specialized view data mapping:
690 typedef ViewSpecializeSacadoFad specialize ;
691
692 typedef typename array_analysis::dimension dimension ;
693 typedef typename array_analysis::value_type value_type ;
694 typedef typename array_analysis::const_value_type const_value_type ;
695 typedef typename array_analysis::non_const_value_type non_const_value_type ;
696
697 // Generate analogous multidimensional array specification type.
698 typedef typename
699 ViewDataType< value_type , dimension >::type type ;
700 typedef typename
701 ViewDataType< const_value_type , dimension >::type const_type ;
702 typedef typename
703 ViewDataType< non_const_value_type , dimension >::type non_const_type ;
704
705private:
706
707 // A const ?
708 enum { is_const = std::is_same< value_type , const_value_type >::value };
709
710 // The unwrapped scalar types:
711 typedef typename
712 std::conditional< is_const , const ScalarType , ScalarType >::type
713 scalar_type ;
714
715 typedef ScalarType non_const_scalar_type ;
716 typedef const ScalarType const_scalar_type ;
717
718 // Append the FAD static dimension
719 typedef typename array_analysis::dimension::
720 template append<( DimFad ? DimFad + 1 : 0 )>::type
721 scalar_dimension ;
722
723public:
724
725 // Generate "flattened" multidimensional array specification type.
726 typedef typename
727 ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
728
729 typedef typename
730 ViewDataType< const_scalar_type , scalar_dimension >::type
731 const_scalar_array_type ;
732
733 typedef typename
734 ViewDataType< non_const_scalar_type , scalar_dimension >::type
735 non_const_scalar_array_type ;
736};
737
738// Specialization for LayoutContiguous, where the Fad type is kept contiguous.
739// This requires a separate view specialization.
740template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad, unsigned Stride >
741struct FadViewDataAnalysis<DataType, LayoutContiguous<ArrayLayout,Stride>, ScalarType, DimFad>
742{
743private:
744
745 typedef ViewArrayAnalysis< DataType > array_analysis ;
746
747public:
748
749 // For now use the default mapping
750 typedef ViewSpecializeSacadoFadContiguous specialize ;
751
752 typedef typename array_analysis::dimension dimension ;
753 typedef typename array_analysis::value_type value_type ;
754 typedef typename array_analysis::const_value_type const_value_type ;
755 typedef typename array_analysis::non_const_value_type non_const_value_type ;
756
757 // Generate analogous multidimensional array specification type.
758 typedef typename
759 ViewDataType< value_type , dimension >::type type ;
760 typedef typename
761 ViewDataType< const_value_type , dimension >::type const_type ;
762 typedef typename
763 ViewDataType< non_const_value_type , dimension >::type non_const_type ;
764
765private:
766
767 // A const ?
768 enum { is_const = std::is_same< value_type , const_value_type >::value };
769
770 // The unwrapped scalar types:
771 typedef typename
772 std::conditional< is_const , const ScalarType , ScalarType >::type
773 scalar_type ;
774
775 typedef ScalarType non_const_scalar_type ;
776 typedef const ScalarType const_scalar_type ;
777
778 // Prepend/append the FAD dimension
779 typedef typename std::conditional<
780 std::is_same< ArrayLayout, Kokkos::LayoutLeft >::value,
781 typename array_analysis::dimension::
782 template prepend<0>::type,
783 typename array_analysis::dimension::
784 template append<0>::type >::type
785 scalar_dimension ;
786
787public:
788
789 // Generate "flattened" multidimensional array specification type.
790 typedef typename
791 ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
792
793 typedef typename
794 ViewDataType< const_scalar_type , scalar_dimension >::type
795 const_scalar_array_type ;
796
797 typedef typename
798 ViewDataType< non_const_scalar_type , scalar_dimension >::type
799 non_const_scalar_array_type ;
800
801};
802
803// Specialization for LayoutNatural, where we don't allow striding within
804// the FadType.
805//
806// Currently this is implemented by choosing the default ViewMapping
807// specialization.
808template< class DataType , class ArrayLayout , class ScalarType , unsigned DimFad >
809struct FadViewDataAnalysis<DataType, LayoutNatural<ArrayLayout>, ScalarType, DimFad>
810{
811private:
812
813 typedef ViewArrayAnalysis< DataType > array_analysis ;
814
815public:
816
817 // For now use the default mapping
818 typedef void specialize ;
819
820 typedef typename array_analysis::dimension dimension ;
821 typedef typename array_analysis::value_type value_type ;
822 typedef typename array_analysis::const_value_type const_value_type ;
823 typedef typename array_analysis::non_const_value_type non_const_value_type ;
824
825 // Generate analogous multidimensional array specification type.
826 typedef typename
827 ViewDataType< value_type , dimension >::type type ;
828 typedef typename
829 ViewDataType< const_value_type , dimension >::type const_type ;
830 typedef typename
831 ViewDataType< non_const_value_type , dimension >::type non_const_type ;
832
833 // Generate "flattened" multidimensional array specification type.
834 typedef type scalar_array_type ;
835 typedef const_type const_scalar_array_type ;
836 typedef non_const_type non_const_scalar_array_type ;
837
838};
839
840} // namespace Impl
841} // namespace Kokkos
842
843//----------------------------------------------------------------------------
844
845namespace Sacado {
846
847namespace Fad { namespace Exp { template< typename > class GeneralFad ; } }
848
849#ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
850namespace Fad { template< typename > class DFad ; }
851namespace Fad { template< typename , int > class SFad ; }
852namespace Fad { template< typename , int > class SLFad ; }
853#endif
854
855namespace CacheFad { template< typename > class DFad ; }
856namespace ELRFad { template< typename > class DFad ; }
857namespace ELRCacheFad { template< typename > class DFad ; }
858
859namespace CacheFad { template< typename , int > class SFad ; }
860namespace ELRFad { template< typename , int > class SFad ; }
861namespace ELRCacheFad { template< typename , int > class SFad ; }
862
863
864namespace CacheFad { template< typename , int > class SLFad ; }
865namespace ELRFad { template< typename , int > class SLFad ; }
866namespace ELRCacheFad { template< typename , int > class SLFad ; }
867}
868
869namespace Kokkos {
870namespace Impl {
871
872#define KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( NS ) \
873template< class DataType , class ArrayLayout , typename ScalarType > \
874struct ViewDataAnalysis \
875 < DataType /* Original view data type */ \
876 , ArrayLayout \
877 , Sacado:: NS ::DFad< ScalarType > \
878 > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , 0 > {}; \
879\
880template< class DataType , class ArrayLayout , typename ScalarType , int N > \
881struct ViewDataAnalysis \
882 < DataType /* Original view data type */ \
883 , ArrayLayout \
884 , Sacado:: NS ::SFad< ScalarType , N > \
885 > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
886 int(Sacado::StaticSize< Sacado:: NS ::SFad< ScalarType , N > >::value) \
887 > {}; \
888\
889template< class DataType , class ArrayLayout , typename ScalarType , int N > \
890struct ViewDataAnalysis \
891 < DataType /* Original view data type */ \
892 , ArrayLayout \
893 , Sacado:: NS ::SLFad< ScalarType , N > \
894 > : public FadViewDataAnalysis< DataType, ArrayLayout, ScalarType , \
895 int(Sacado::StaticSize< Sacado:: NS ::SLFad< ScalarType , N > >::value) \
896 > {}; \
897
898template< class DataType , class ArrayLayout , typename StorageType >
899struct ViewDataAnalysis
900 < DataType /* Original view data type */
901 , ArrayLayout
902 , Sacado::Fad::Exp::GeneralFad< StorageType >
903 > : public FadViewDataAnalysis< DataType, ArrayLayout, typename StorageType::value_type , 0 > {};
904
905#ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
906KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( Fad )
907#endif
908
909KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( CacheFad )
910KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRFad )
911KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD( ELRCacheFad )
912
913#undef KOKKOS_VIEW_DATA_ANALYSIS_SACADO_FAD
914
915} // namespace Impl
916} // namespace Kokkos
917
918//----------------------------------------------------------------------------
919
920namespace Kokkos {
921
922// Copied from Sacado_ViewFactory
923template <class View, class ... ViewPack>
924KOKKOS_INLINE_FUNCTION
925unsigned dimension_scalar(const View& v, const ViewPack&... views) {
926 const unsigned dim0 = dimension_scalar(v);
927 const unsigned dim1 = dimension_scalar(views...);
928 return dim0 >= dim1 ? dim0 : dim1 ;
929}
930
931} // namespace Kokkos
932
933//----------------------------------------------------------------------------
934
935namespace Kokkos { namespace Impl {
936
937template < typename Specialize, typename A, typename B >
938struct CommonViewValueType;
939
940template < typename A, typename B >
941struct CommonViewValueType< Kokkos::Impl::ViewSpecializeSacadoFad, A, B >
942{
943 using value_type = typename Sacado::Promote<A,B>::type ;
944};
945
946template < typename A, typename B >
947struct CommonViewValueType< Kokkos::Impl::ViewSpecializeSacadoFadContiguous, A, B >
948{
949 using value_type = typename Sacado::Promote<A,B>::type ;
950};
951
952
953template < class Specialize, class ValueType >
954struct CommonViewAllocProp;
955
956template < class ValueType >
957struct CommonViewAllocProp< Kokkos::Impl::ViewSpecializeSacadoFad, ValueType >
958{
959 using value_type = ValueType;
960 using scalar_array_type = typename Sacado::ValueType< value_type >::type;
961 unsigned fad_dim;
962 bool is_view_type;
963
964 KOKKOS_INLINE_FUNCTION
965 CommonViewAllocProp()
966 : fad_dim(0) , is_view_type(false) {}
967
968 // Assume all views are View or DynRankView
969 // TODO If assumption is insufficient, better deduction on is_view...
970 template < class View >
971 KOKKOS_INLINE_FUNCTION
972 CommonViewAllocProp( const View & view )
973 : fad_dim ( dimension_scalar(view) )
974 {
975 is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
976 }
977
978 // TODO If assumption is insufficient, better deduction on is_view...
979 template < class View, class ... Views >
980 KOKKOS_INLINE_FUNCTION
981 CommonViewAllocProp( const View & view, const Views & ... views )
982 : fad_dim ( dimension_scalar(view, views... ) )
983 {
984 is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
985 }
986
987};
988
989template < class ValueType >
990struct CommonViewAllocProp< Kokkos::Impl::ViewSpecializeSacadoFadContiguous, ValueType >
991{
992 using value_type = ValueType;
993 using scalar_array_type = typename Sacado::ValueType< value_type >::type;
994 unsigned fad_dim;
995 bool is_view_type;
996
997 KOKKOS_INLINE_FUNCTION
998 CommonViewAllocProp()
999 : fad_dim(0) , is_view_type(false) {}
1000
1001 // Assume all views are View or DynRankView
1002 // TODO If assumption is insufficient, better deduction on is_view...
1003 template < class View >
1004 KOKKOS_INLINE_FUNCTION
1005 CommonViewAllocProp( const View & view )
1006 : fad_dim ( dimension_scalar(view) )
1007 {
1008 is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
1009 }
1010
1011 // TODO If assumption is insufficient, better deduction on is_view...
1012 template < class View, class ... Views >
1013 KOKKOS_INLINE_FUNCTION
1014 CommonViewAllocProp( const View & view, const Views & ... views )
1015 : fad_dim ( dimension_scalar(view, views... ) )
1016 {
1017 is_view_type = (Kokkos::is_view<View>::value || Kokkos::is_view_fad<View>::value);
1018 }
1019};
1020
1021// Detect if a ViewCtorProp contains a CommonViewAllocProp
1022template < typename ... P >
1023struct has_common_view_alloc_prop : public std::false_type {};
1024
1025template < class Specialize, class ValueType >
1026struct has_common_view_alloc_prop< CommonViewAllocProp<Specialize, ValueType> > : public std::true_type {};
1027
1028
1029// Check for CommonViewAllocProp in pack of properties
1030template < typename ... >
1031struct check_has_common_view_alloc_prop;
1032
1033template <>
1034struct check_has_common_view_alloc_prop<>
1035{
1036 enum { value = false };
1037};
1038
1039template < typename P >
1040struct check_has_common_view_alloc_prop<P>
1041{
1042 enum { value = has_common_view_alloc_prop< P >::value };
1043};
1044
1045template < typename P0, typename ... P >
1046struct check_has_common_view_alloc_prop<P0, P...>
1047{
1048 enum { value = ( (has_common_view_alloc_prop<P0>::value == true) ? true : check_has_common_view_alloc_prop<P...>::value ) };
1049};
1050
1051template < typename ... >
1052struct compute_fad_dim_from_alloc_prop;
1053
1054template < >
1055struct compute_fad_dim_from_alloc_prop<> {
1056 template <typename CtorProp>
1057 KOKKOS_INLINE_FUNCTION
1058 static unsigned eval(const CtorProp&) { return 0; }
1059};
1060
1061template < typename P >
1062struct compute_fad_dim_from_alloc_prop<P> {
1063 template <typename CtorProp>
1064 KOKKOS_INLINE_FUNCTION
1065 static unsigned eval(const CtorProp&) { return 0; }
1066};
1067
1068template < typename P0, typename ... P >
1069struct compute_fad_dim_from_alloc_prop<P0,P...> {
1070 template <typename CtorProp>
1071 KOKKOS_INLINE_FUNCTION
1072 static unsigned eval(const CtorProp& prop) {
1073 unsigned d1 = compute_fad_dim_from_alloc_prop<P0>::eval(prop);
1074 unsigned d2 = compute_fad_dim_from_alloc_prop<P...>::eval(prop);
1075 return d1 > d2 ? d1 : d2;
1076 }
1077};
1078
1079template < class ValueType >
1080struct compute_fad_dim_from_alloc_prop<
1081 CommonViewAllocProp<ViewSpecializeSacadoFad, ValueType>
1082 > {
1083 template <typename CtorProp>
1084 KOKKOS_INLINE_FUNCTION
1085 static unsigned eval(const CtorProp& prop) {
1086 using specialize = ViewSpecializeSacadoFad;
1087 using CVAP = CommonViewAllocProp< specialize, ValueType >;
1088 auto cast_prop = ((Kokkos::Impl::ViewCtorProp<void, CVAP> const &)prop).value;
1089 return cast_prop.fad_dim;
1090 }
1091};
1092
1093template < class ValueType >
1094struct compute_fad_dim_from_alloc_prop<
1095 CommonViewAllocProp<ViewSpecializeSacadoFadContiguous, ValueType>
1096 > {
1097 template <typename CtorProp>
1098 KOKKOS_INLINE_FUNCTION
1099 static unsigned eval(const CtorProp& prop) {
1100 using specialize = ViewSpecializeSacadoFadContiguous;
1101 using CVAP = CommonViewAllocProp< specialize, ValueType >;
1102 auto cast_prop = ((Kokkos::Impl::ViewCtorProp<void, CVAP> const &)prop).value;
1103 return cast_prop.fad_dim;
1104 }
1105};
1106
1107template <typename Traits, typename ... P >
1108struct appendFadToLayoutViewAllocHelper
1109{
1110 using layout_type = typename Traits::array_layout;
1111 using specialize = typename Traits::specialize;
1112 using CtorProp = ViewCtorProp< P... >;
1113
1114 KOKKOS_INLINE_FUNCTION
1115 static layout_type returnNewLayoutPlusFad( const CtorProp & arg_prop, const layout_type & arg_layout ) {
1116
1117 layout_type appended_layout( arg_layout );
1118
1119 // Static View case - DynRankView layout handled within createLayout calls
1120
1121 const unsigned fad_dim =
1122 compute_fad_dim_from_alloc_prop<P...>::eval(arg_prop);
1123 appended_layout.dimension[ Traits::rank ] = (fad_dim > 0) ? fad_dim : 1;
1124
1125 return appended_layout;
1126 }
1127};
1128
1129template <typename Layout>
1130struct prependFadToLayout
1131{
1132 using layout_type = Layout;
1133
1134 template < typename FadSizeType >
1135 KOKKOS_INLINE_FUNCTION
1136 static layout_type returnNewLayoutPlusFad( const layout_type & arg_layout, const FadSizeType fad_dim ) {
1137
1138 layout_type prepended_layout(0,0,0,0,0,0,0,0);
1139
1140 prepended_layout.dimension[0] = fad_dim;
1141
1142 for ( int i = 1; i < ARRAY_LAYOUT_MAX_RANK; ++i ) {
1143 prepended_layout.dimension[i] = arg_layout.dimension[i-1];
1144 }
1145
1146 return prepended_layout;
1147 }
1148};
1149
1150} } // namespace Kokkos::Impl
1151
1152
1153//----------------------------------------------------------------------------
1154
1155
1156namespace Kokkos {
1157namespace Impl {
1158
1159template< class Traits >
1160class ViewMapping< Traits , /* View internal mapping */
1161 typename std::enable_if<
1162 ( std::is_same< typename Traits::specialize
1163 , ViewSpecializeSacadoFad >::value
1164 &&
1165 ( std::is_same< typename Traits::array_layout
1166 , Kokkos::LayoutLeft >::value
1167 ||
1168 std::is_same< typename Traits::array_layout
1169 , Kokkos::LayoutRight >::value
1170 ||
1171 std::is_same< typename Traits::array_layout
1172 , Kokkos::LayoutStride >::value
1173 )
1174 )
1175 , typename Traits::specialize
1176 >::type >
1177{
1178private:
1179
1180 template< class , class ... > friend class ViewMapping ;
1181 template< class , class ... > friend class Kokkos::View ;
1182
1183 typedef typename Traits::value_type fad_type ;
1184 typedef typename Sacado::ValueType< fad_type >::type fad_value_type ;
1185 typedef typename
1186 std::add_const< fad_value_type >::type const_fad_value_type ;
1187
1188 enum { FadStaticDimension = Sacado::StaticSize< fad_type >::value };
1189 typedef Sacado::integral_nonzero< unsigned , FadStaticDimension > sacado_size_type;
1190
1191 // Only LayoutRight has a static stride one
1192 enum { FadStaticStride =
1193 std::is_same< typename Traits::array_layout
1194 , Kokkos::LayoutRight >::value ? 1 : 0 };
1195
1196 typedef Sacado::integral_nonzero< unsigned , FadStaticStride > sacado_stride_type;
1197
1198 typedef fad_value_type * handle_type ;
1199
1200 typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
1201
1202 // Offset without Fad dimension
1203 typedef ViewOffset< typename Traits::dimension
1204 , typename Traits::array_layout
1205 , void
1206 > offset_type ;
1207
1208 // Append the fad dimension for the internal offset mapping.
1209 typedef ViewOffset
1210 < typename array_analysis::dimension::
1211 template append<( unsigned(FadStaticDimension) > 0 ? unsigned(FadStaticDimension) + 1 : 0 )>::type
1212 , typename Traits::array_layout
1213 , void
1214 > array_offset_type ;
1215
1216 handle_type m_impl_handle ;
1217 offset_type m_impl_offset ;
1218 array_offset_type m_array_offset ;
1219 sacado_size_type m_fad_size ;
1220 sacado_stride_type m_fad_stride ;
1221
1222public:
1223
1224 //----------------------------------------
1225 // Domain dimensions
1226
1227 enum { Rank = Traits::dimension::rank };
1228
1229 // Using the internal offset mapping so limit to public rank:
1230 template< typename iType >
1231 KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
1232 { return m_impl_offset.m_dim.extent(r) ; }
1233
1234 KOKKOS_INLINE_FUNCTION constexpr
1235 typename Traits::array_layout layout() const
1236 { return m_impl_offset.layout(); }
1237
1238 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
1239 { return m_impl_offset.dimension_0(); }
1240 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
1241 { return m_impl_offset.dimension_1(); }
1242 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
1243 { return m_impl_offset.dimension_2(); }
1244 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
1245 { return m_impl_offset.dimension_3(); }
1246 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
1247 { return m_impl_offset.dimension_4(); }
1248 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
1249 { return m_impl_offset.dimension_5(); }
1250 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
1251 { return m_impl_offset.dimension_6(); }
1252 KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
1253 { return m_impl_offset.dimension_7(); }
1254
1255 // Can only be regular layout with uniform striding
1256 // when LayoutRight with contiguous values so not guaranteed true.
1257 using is_regular = std::false_type ;
1258
1259 KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const
1260 { return m_impl_offset.stride_0(); }
1261 KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const
1262 { return m_impl_offset.stride_1(); }
1263 KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const
1264 { return m_impl_offset.stride_2(); }
1265 KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const
1266 { return m_impl_offset.stride_3(); }
1267 KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const
1268 { return m_impl_offset.stride_4(); }
1269 KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const
1270 { return m_impl_offset.stride_5(); }
1271 KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const
1272 { return m_impl_offset.stride_6(); }
1273 KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const
1274 { return m_impl_offset.stride_7(); }
1275
1276 template< typename iType >
1277 KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const
1278 { m_impl_offset.stride(s) ; }
1279
1280 // Size of sacado scalar dimension
1281 KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
1282 { return m_fad_size.value+1; }
1283
1284 // trode of sacado scalar dimension
1285 KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned stride_scalar() const
1286 { return m_fad_stride.value; }
1287
1288 //----------------------------------------
1289 // Range of mapping
1290
1291 // Return type of reference operators
1292 typedef typename
1293 Sacado::ViewFadType< fad_type , FadStaticDimension , FadStaticStride >::type reference_type ;
1294
1296 typedef fad_value_type * pointer_type ;
1297
1299 KOKKOS_INLINE_FUNCTION constexpr size_t span() const
1300 { return m_array_offset.span(); }
1301
1303 KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
1304 { return m_array_offset.span_is_contiguous() ; }
1305
1307 KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
1308 { return m_impl_handle ; }
1309
1310 //----------------------------------------
1311
1312 KOKKOS_FORCEINLINE_FUNCTION
1313 reference_type reference() const
1314 { return reference_type( m_impl_handle
1315 , m_fad_size.value
1316 , m_fad_stride.value ); }
1317
1318 template< typename I0 >
1319 KOKKOS_FORCEINLINE_FUNCTION
1320 reference_type
1321 reference( const I0 & i0 ) const
1322 { return reference_type( m_impl_handle + m_array_offset(i0,0)
1323 , m_fad_size.value
1324 , m_fad_stride.value ); }
1325
1326 template< typename I0 , typename I1 >
1327 KOKKOS_FORCEINLINE_FUNCTION
1328 reference_type reference( const I0 & i0 , const I1 & i1 ) const
1329 { return reference_type( m_impl_handle + m_array_offset(i0,i1,0)
1330 , m_fad_size.value
1331 , m_fad_stride.value ); }
1332
1333
1334 template< typename I0 , typename I1 , typename I2 >
1335 KOKKOS_FORCEINLINE_FUNCTION
1336 reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
1337 { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,0)
1338 , m_fad_size.value
1339 , m_fad_stride.value ); }
1340
1341 template< typename I0 , typename I1 , typename I2 , typename I3 >
1342 KOKKOS_FORCEINLINE_FUNCTION
1343 reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
1344 { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,0)
1345 , m_fad_size.value
1346 , m_fad_stride.value ); }
1347
1348 template< typename I0 , typename I1 , typename I2 , typename I3
1349 , typename I4 >
1350 KOKKOS_FORCEINLINE_FUNCTION
1351 reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1352 , const I4 & i4 ) const
1353 { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,0)
1354 , m_fad_size.value
1355 , m_fad_stride.value ); }
1356
1357 template< typename I0 , typename I1 , typename I2 , typename I3
1358 , typename I4 , typename I5 >
1359 KOKKOS_FORCEINLINE_FUNCTION
1360 reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1361 , const I4 & i4 , const I5 & i5 ) const
1362 { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,i5,0)
1363 , m_fad_size.value
1364 , m_fad_stride.value ); }
1365
1366
1367 template< typename I0 , typename I1 , typename I2 , typename I3
1368 , typename I4 , typename I5 , typename I6 >
1369 KOKKOS_FORCEINLINE_FUNCTION
1370 reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
1371 , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
1372 { return reference_type( m_impl_handle + m_array_offset(i0,i1,i2,i3,i4,i5,i6,0)
1373 , m_fad_size.value
1374 , m_fad_stride.value ); }
1375
1376 //----------------------------------------
1377
1379 KOKKOS_INLINE_FUNCTION
1380 static size_t memory_span( typename Traits::array_layout const & layout )
1381 {
1382 size_t dims[8];
1383 for (int i=0; i<8; ++i)
1384 dims[i] = layout.dimension[i];
1385 if (unsigned(FadStaticDimension) > 0)
1386 dims[unsigned(Rank)] = FadStaticDimension+1;
1387
1388 typename Traits::array_layout alayout(
1389 dims[0], dims[1], dims[2], dims[3],
1390 dims[4], dims[5], dims[6], dims[7] );
1391
1392 // Do not introduce padding...
1393 typedef std::integral_constant< unsigned , 0 > padding ;
1394 return array_offset_type( padding() , alayout ).span() * sizeof(fad_value_type);
1395 }
1396
1397 //----------------------------------------
1398
1399 KOKKOS_INLINE_FUNCTION ~ViewMapping() {}
1400 KOKKOS_INLINE_FUNCTION ViewMapping() : m_impl_handle(0) , m_impl_offset() , m_array_offset() , m_fad_size(0) , m_fad_stride(0) {}
1401
1402 KOKKOS_DEFAULTED_FUNCTION ViewMapping( const ViewMapping & ) = default ;
1403 KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
1404
1405 KOKKOS_DEFAULTED_FUNCTION ViewMapping( ViewMapping && ) = default ;
1406 KOKKOS_DEFAULTED_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
1407
1408 template< class ... P >
1409 KOKKOS_INLINE_FUNCTION
1410 ViewMapping
1411 ( ViewCtorProp< P ... > const & prop
1412 , typename Traits::array_layout const & local_layout
1413 )
1414 : m_impl_handle( ( (ViewCtorProp<void,pointer_type> const &) prop ).value )
1415 , m_impl_offset( std::integral_constant< unsigned , 0 >()
1416 , local_layout )
1417 , m_array_offset( std::integral_constant< unsigned , 0 >()
1418 , local_layout )
1419 // Query m_array_offset, not input, in case of static dimension
1420 , m_fad_size(
1421 ( Rank == 0 ? m_array_offset.dimension_0() :
1422 ( Rank == 1 ? m_array_offset.dimension_1() :
1423 ( Rank == 2 ? m_array_offset.dimension_2() :
1424 ( Rank == 3 ? m_array_offset.dimension_3() :
1425 ( Rank == 4 ? m_array_offset.dimension_4() :
1426 ( Rank == 5 ? m_array_offset.dimension_5() :
1427 ( Rank == 6 ? m_array_offset.dimension_6() :
1428 m_array_offset.dimension_7() ))))))) - 1 )
1429 , m_fad_stride(
1430 ( Rank == 0 ? m_array_offset.stride_0() :
1431 ( Rank == 1 ? m_array_offset.stride_1() :
1432 ( Rank == 2 ? m_array_offset.stride_2() :
1433 ( Rank == 3 ? m_array_offset.stride_3() :
1434 ( Rank == 4 ? m_array_offset.stride_4() :
1435 ( Rank == 5 ? m_array_offset.stride_5() :
1436 ( Rank == 6 ? m_array_offset.stride_6() :
1437 m_array_offset.stride_7() ))))))))
1438
1439 {
1440 const unsigned fad_dim =
1441 ( Rank == 0 ? m_array_offset.dimension_0() :
1442 ( Rank == 1 ? m_array_offset.dimension_1() :
1443 ( Rank == 2 ? m_array_offset.dimension_2() :
1444 ( Rank == 3 ? m_array_offset.dimension_3() :
1445 ( Rank == 4 ? m_array_offset.dimension_4() :
1446 ( Rank == 5 ? m_array_offset.dimension_5() :
1447 ( Rank == 6 ? m_array_offset.dimension_6() :
1448 m_array_offset.dimension_7() )))))));
1449 if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
1450 Kokkos::abort("invalid fad dimension (0) supplied!");
1451 }
1452
1453 //----------------------------------------
1454 /* Allocate and construct mapped array.
1455 * Allocate via shared allocation record and
1456 * return that record for allocation tracking.
1457 */
1458 template< class ... P >
1459 SharedAllocationRecord<> *
1460 allocate_shared( ViewCtorProp< P... > const & prop
1461 , typename Traits::array_layout const & local_layout
1462 , bool execution_space_specified)
1463 {
1464 typedef ViewCtorProp< P... > ctor_prop ;
1465
1466 typedef typename ctor_prop::execution_space execution_space ;
1467 typedef typename Traits::memory_space memory_space ;
1468 typedef ViewValueFunctor< execution_space , fad_value_type > functor_type ;
1469 typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
1470
1471 // Disallow padding
1472 typedef std::integral_constant< unsigned , 0 > padding ;
1473
1474 // Check if ViewCtorProp has CommonViewAllocProp - if so, retrieve the fad_size and append to layout
1475 enum { test_traits_check = Kokkos::Impl::check_has_common_view_alloc_prop< P... >::value };
1476
1477 m_impl_offset = offset_type( padding(), local_layout );
1478
1479 typename Traits::array_layout internal_layout =
1480 (test_traits_check == true)
1481 ? Kokkos::Impl::appendFadToLayoutViewAllocHelper< Traits, P... >::returnNewLayoutPlusFad(prop, local_layout)
1482 : local_layout;
1483
1484 m_array_offset = array_offset_type( padding(), internal_layout );
1485
1486 const unsigned fad_dim =
1487 ( Rank == 0 ? m_array_offset.dimension_0() :
1488 ( Rank == 1 ? m_array_offset.dimension_1() :
1489 ( Rank == 2 ? m_array_offset.dimension_2() :
1490 ( Rank == 3 ? m_array_offset.dimension_3() :
1491 ( Rank == 4 ? m_array_offset.dimension_4() :
1492 ( Rank == 5 ? m_array_offset.dimension_5() :
1493 ( Rank == 6 ? m_array_offset.dimension_6() :
1494 m_array_offset.dimension_7() )))))));
1495 if (unsigned(FadStaticDimension) == 0 && fad_dim == 0)
1496 Kokkos::abort("invalid fad dimension (0) supplied!");
1497 m_fad_size = fad_dim - 1 ;
1498
1499 m_fad_stride =
1500 ( Rank == 0 ? m_array_offset.stride_0() :
1501 ( Rank == 1 ? m_array_offset.stride_1() :
1502 ( Rank == 2 ? m_array_offset.stride_2() :
1503 ( Rank == 3 ? m_array_offset.stride_3() :
1504 ( Rank == 4 ? m_array_offset.stride_4() :
1505 ( Rank == 5 ? m_array_offset.stride_5() :
1506 ( Rank == 6 ? m_array_offset.stride_6() :
1507 m_array_offset.stride_7() )))))));
1508
1509 const size_t alloc_size = m_array_offset.span() * sizeof(fad_value_type);
1510
1511 // Create shared memory tracking record with allocate memory from the memory space
1512 record_type * const record =
1513 record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
1514 , ( (ViewCtorProp<void,std::string> const &) prop ).value
1515 , alloc_size );
1516
1517 // Only set the the pointer and initialize if the allocation is non-zero.
1518 // May be zero if one of the dimensions is zero.
1519 if ( alloc_size ) {
1520
1521 m_impl_handle = handle_type( reinterpret_cast< pointer_type >( record->data() ) );
1522
1523 if ( ctor_prop::initialize ) {
1524 // Assume destruction is only required when construction is requested.
1525 // The ViewValueFunctor has both value construction and destruction operators.
1526 if (execution_space_specified)
1527 record->m_destroy = functor_type( ( (ViewCtorProp<void,execution_space> const &) prop).value
1528 , (fad_value_type *) m_impl_handle
1529 , m_array_offset.span()
1530 , record->get_label()
1531 );
1532 else
1533 record->m_destroy = functor_type((fad_value_type *) m_impl_handle
1534 , m_array_offset.span()
1535 , record->get_label()
1536 );
1537
1538 // Construct values
1539 record->m_destroy.construct_shared_allocation();
1540 }
1541 }
1542
1543 return record ;
1544 }
1545
1546};
1547
1548} // namespace Impl
1549} // namespace Kokkos
1550
1551//----------------------------------------------------------------------------
1552
1553namespace Kokkos {
1554namespace Impl {
1555
1560template< class DstTraits , class SrcTraits >
1561class ViewMapping< DstTraits , SrcTraits ,
1562 typename std::enable_if<(
1563 Kokkos::Impl::MemorySpaceAccess
1564 < typename DstTraits::memory_space
1565 , typename SrcTraits::memory_space >::assignable
1566 &&
1567 // Destination view has FAD
1568 std::is_same< typename DstTraits::specialize
1569 , ViewSpecializeSacadoFad >::value
1570 &&
1571 // Source view has FAD
1572 std::is_same< typename SrcTraits::specialize
1573 , ViewSpecializeSacadoFad >::value
1574
1575 )
1576 , typename DstTraits::specialize
1577 >::type >
1578{
1579public:
1580
1581 enum { is_assignable = true };
1582 enum { is_assignable_data_type = true };
1583
1584 typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1585 typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1586 typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1587
1588 template< class DstType >
1589 KOKKOS_INLINE_FUNCTION static
1590 void assign( DstType & dst
1591 , const SrcFadType & src
1592 , const TrackType & )
1593 {
1594 static_assert(
1595 (
1596 std::is_same< typename DstTraits::array_layout
1597 , Kokkos::LayoutLeft >::value ||
1598 std::is_same< typename DstTraits::array_layout
1599 , Kokkos::LayoutRight >::value ||
1600 std::is_same< typename DstTraits::array_layout
1601 , Kokkos::LayoutStride >::value
1602 )
1603 &&
1604 (
1605 std::is_same< typename SrcTraits::array_layout
1606 , Kokkos::LayoutLeft >::value ||
1607 std::is_same< typename SrcTraits::array_layout
1608 , Kokkos::LayoutRight >::value ||
1609 std::is_same< typename SrcTraits::array_layout
1610 , Kokkos::LayoutStride >::value
1611 )
1612 , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1613
1614 static_assert(
1615 std::is_same< typename DstTraits::array_layout
1616 , typename SrcTraits::array_layout >::value ||
1617 std::is_same< typename DstTraits::array_layout
1618 , Kokkos::LayoutStride >::value ,
1619 "View assignment must have compatible layout" );
1620
1621 static_assert(
1622 std::is_same< typename DstTraits::value_type
1623 , typename SrcTraits::value_type >::value ||
1624 std::is_same< typename DstTraits::value_type
1625 , typename SrcTraits::const_value_type >::value ,
1626 "View assignment must have same value type or const = non-const" );
1627
1628 static_assert(
1629 ViewDimensionAssignable
1630 < typename DstType::offset_type::dimension_type
1631 , typename SrcFadType::offset_type::dimension_type >::value ,
1632 "View assignment must have compatible dimensions" );
1633
1634 static_assert(
1635 ViewDimensionAssignable
1636 < typename DstType::array_offset_type::dimension_type
1637 , typename SrcFadType::array_offset_type::dimension_type >::value ,
1638 "View assignment must have compatible dimensions" );
1639
1640 typedef typename DstType::offset_type dst_offset_type ;
1641 typedef typename DstType::array_offset_type dst_array_offset_type ;
1642
1643 dst.m_impl_handle = src.m_impl_handle ;
1644 dst.m_impl_offset = dst_offset_type( src.m_impl_offset );
1645 dst.m_array_offset = dst_array_offset_type( src.m_array_offset );
1646 dst.m_fad_size = src.m_fad_size.value ;
1647 dst.m_fad_stride = src.m_fad_stride.value ;
1648 }
1649};
1650
1651// Integer argument is the actual rank => ranks 0 to Rank-1 will be assigned
1657template< class DstTraits , class SrcTraits >
1658class ViewMapping< DstTraits , SrcTraits ,
1659 typename std::enable_if<(
1660 Kokkos::Impl::MemorySpaceAccess
1661 < typename DstTraits::memory_space
1662 , typename SrcTraits::memory_space >::assignable
1663 &&
1664 // Destination view has ordinary
1665 std::is_same< typename DstTraits::specialize , void >::value
1666 &&
1667 // Source view has FAD only
1668 std::is_same< typename SrcTraits::specialize
1669 , ViewSpecializeSacadoFad >::value
1670 )
1671 , typename DstTraits::specialize
1672 >::type >
1673{
1674public:
1675
1676 enum { is_assignable = true };
1677 enum { is_assignable_data_type = true };
1678
1679
1680 typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1681 typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1682 typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1683
1684
1685 // Helpers to assign, and generate if necessary, ViewOffset to the dst map
1686 // These are necessary to use Kokkos' deep_copy with nested fads
1687 template < class DstType, class SrcFadType, class Truth = void >
1688 struct AssignOffset;
1689
1690 template < class DstType, class SrcFadType >
1691 struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank != (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
1692 {
1693 // ViewOffset's Dimensions Ranks do not match
1694 KOKKOS_INLINE_FUNCTION
1695 static void assign( DstType & dst, const SrcFadType & src )
1696 {
1697 typedef typename SrcTraits::value_type TraitsValueType;
1698
1700 && Sacado::IsStaticallySized< typename Sacado::ValueType< TraitsValueType >::type >::value
1701 )
1702 {
1703 typedef typename DstType::offset_type::array_layout DstLayoutType;
1704 //typedef typename ViewArrayLayoutSelector<typename DstType::offset_type::array_layout>::type DstLayoutType;
1705 typedef typename SrcFadType::array_offset_type::dimension_type SrcViewDimension;
1706
1707 // This is the static dimension of the inner fad, missing from ViewDimension
1708 const size_t InnerStaticDim = Sacado::StaticSize< typename Sacado::ValueType< TraitsValueType >::type >::value;
1709
1710 static constexpr bool is_layout_left =
1711 std::is_same< DstLayoutType, Kokkos::LayoutLeft>::value;
1712
1713 typedef typename std::conditional< is_layout_left,
1714 typename SrcViewDimension:: template prepend< InnerStaticDim+1 >::type,
1715 typename SrcViewDimension:: template append < InnerStaticDim+1 >::type
1716 >::type SrcViewDimensionAppended;
1717
1718 typedef std::integral_constant< unsigned , 0 > padding ;
1719
1720 typedef ViewOffset< SrcViewDimensionAppended, DstLayoutType > TmpOffsetType;
1721
1722 auto src_layout = src.m_array_offset.layout();
1723
1724 if ( is_layout_left ) {
1725 auto prepend_layout = Kokkos::Impl::prependFadToLayout< DstLayoutType >::returnNewLayoutPlusFad(src_layout, InnerStaticDim+1);
1726 TmpOffsetType offset_tmp( padding(), prepend_layout );
1727 dst.m_impl_offset = offset_tmp;
1728 }
1729 else {
1730 TmpOffsetType offset_tmp( padding(), src_layout );
1731 dst.m_impl_offset = offset_tmp;
1732 }
1733
1734 } else {
1735 Kokkos::abort("Sacado error: Applying AssignOffset for case with nested Fads, but without nested Fads - something went wrong");
1736 }
1737 }
1738 };
1739
1740 template < class DstType, class SrcFadType >
1741 struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank == (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
1742 {
1743 KOKKOS_INLINE_FUNCTION
1744 static void assign( DstType & dst, const SrcFadType & src )
1745 {
1746
1747 typedef typename DstType::offset_type dst_offset_type ;
1748 dst.m_impl_offset = dst_offset_type( src.m_array_offset );
1749 }
1750 };
1751
1752
1753// If the dst and src mappings are not equal in Rank, the src should come from a View of nested fads
1754// In the case of two nested fads, the innermost must be an SFad (static Fad)
1755// The offset_type's are not compatible in the case of nested fads because the ViewDimension's ranks will not agree
1756// In this case, rather than trying to construct an offset_type from src (which will fail at compile time)
1757// and assign to dst.m_impl_offset, manually assign the ViewDimension arguments to dst;
1758// requires appending the missing inner SFad dim + 1 to the Rank-1 ViewDimension
1759 // DstType and SrcFadType are MAPS...
1760 template < class DstType >
1761 KOKKOS_INLINE_FUNCTION static
1762 void
1763 assign( DstType & dst
1764 , const SrcFadType & src
1765 , const TrackType &
1766 )
1767 {
1768
1769 static_assert(
1770 (
1771 std::is_same< typename DstTraits::array_layout
1772 , Kokkos::LayoutLeft >::value ||
1773 std::is_same< typename DstTraits::array_layout
1774 , Kokkos::LayoutRight >::value ||
1775 std::is_same< typename DstTraits::array_layout
1776 , Kokkos::LayoutStride >::value
1777 )
1778 &&
1779 (
1780 std::is_same< typename SrcTraits::array_layout
1781 , Kokkos::LayoutLeft >::value ||
1782 std::is_same< typename SrcTraits::array_layout
1783 , Kokkos::LayoutRight >::value ||
1784 std::is_same< typename SrcTraits::array_layout
1785 , Kokkos::LayoutStride >::value
1786 )
1787 , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1788
1789 static_assert(
1790 std::is_same< typename DstTraits::array_layout
1791 , typename SrcTraits::array_layout >::value ||
1792 std::is_same< typename DstTraits::array_layout
1793 , Kokkos::LayoutStride >::value ,
1794 "View assignment must have compatible layout" );
1795#if 0
1796 static_assert(
1797 std::is_same< typename DstTraits::scalar_array_type
1798 , typename SrcTraits::scalar_array_type >::value ||
1799 std::is_same< typename DstTraits::scalar_array_type
1800 , typename SrcTraits::const_scalar_array_type >::value ,
1801 "View assignment must have same value type or const = non-const" );
1802#endif
1803
1804 AssignOffset< DstType, SrcFadType >::assign( dst, src );
1805
1806 dst.m_impl_handle = reinterpret_cast< typename DstType::handle_type >(src.m_impl_handle) ;
1807 }
1808};
1809
1810} // namespace Impl
1811} // namespace Kokkos
1812
1813//----------------------------------------------------------------------------
1814
1815namespace Kokkos {
1816namespace Impl {
1817
1818// Subview mapping
1819
1820template< class SrcTraits , class ... Args >
1821struct ViewMapping
1822 < typename std::enable_if<(
1823 // Source view has FAD only
1824 std::is_same< typename SrcTraits::specialize
1825 , ViewSpecializeSacadoFad >::value
1826 &&
1827 (
1828 std::is_same< typename SrcTraits::array_layout
1829 , Kokkos::LayoutLeft >::value ||
1830 std::is_same< typename SrcTraits::array_layout
1831 , Kokkos::LayoutRight >::value ||
1832 std::is_same< typename SrcTraits::array_layout
1833 , Kokkos::LayoutStride >::value
1834 )
1835 )
1836 >::type
1837 , SrcTraits
1838 , Args ... >
1839{
1840private:
1841
1842 static_assert( SrcTraits::rank == sizeof...(Args) , "" );
1843
1844 enum
1845 { RZ = false
1846 , R0 = bool(is_integral_extent<0,Args...>::value)
1847 , R1 = bool(is_integral_extent<1,Args...>::value)
1848 , R2 = bool(is_integral_extent<2,Args...>::value)
1849 , R3 = bool(is_integral_extent<3,Args...>::value)
1850 , R4 = bool(is_integral_extent<4,Args...>::value)
1851 , R5 = bool(is_integral_extent<5,Args...>::value)
1852 , R6 = bool(is_integral_extent<6,Args...>::value)
1853 };
1854
1855 // Public rank
1856 enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
1857 + unsigned(R4) + unsigned(R5) + unsigned(R6) };
1858
1859 // Whether right-most non-FAD rank is a range.
1860 enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
1861 1 == SrcTraits::rank ? R0 : (
1862 2 == SrcTraits::rank ? R1 : (
1863 3 == SrcTraits::rank ? R2 : (
1864 4 == SrcTraits::rank ? R3 : (
1865 5 == SrcTraits::rank ? R4 : (
1866 6 == SrcTraits::rank ? R5 : R6 ))))))) };
1867
1868 // Subview's layout
1869 // If LayoutRight then FAD is contiguous
1870 // For LayoutLeft, result is LayoutLeft only if 1st arg is a range,
1871 // and since last (FAD) dimension is also a range, and these
1872 // ranges must be consecutive, the input rank must be 1
1873 typedef typename std::conditional<
1874 ( /* Same layout IF */
1875 ( rank == 0 )
1876 ||
1877 ( std::is_same< typename SrcTraits::array_layout
1878 , Kokkos::LayoutRight >::value
1879 &&
1880 ( rank == 1 ) && R0_rev
1881 )
1882 ||
1883 ( std::is_same< typename SrcTraits::array_layout
1884 , Kokkos::LayoutLeft >::value
1885 &&
1886 ( rank == 1 ) && (SrcTraits::rank == 1) && R0
1887 )
1888 ), typename SrcTraits::array_layout , Kokkos::LayoutStride
1889 >::type array_layout ;
1890
1891 typedef typename SrcTraits::value_type fad_type ;
1892
1893 typedef typename std::conditional< rank == 0 , fad_type ,
1894 typename std::conditional< rank == 1 , fad_type * ,
1895 typename std::conditional< rank == 2 , fad_type ** ,
1896 typename std::conditional< rank == 3 , fad_type *** ,
1897 typename std::conditional< rank == 4 , fad_type **** ,
1898 typename std::conditional< rank == 5 , fad_type ***** ,
1899 typename std::conditional< rank == 6 , fad_type ****** ,
1900 fad_type *******
1901 >::type >::type >::type >::type >::type >::type >::type
1902 data_type ;
1903
1904public:
1905
1906 typedef Kokkos::ViewTraits
1907 < data_type
1908 , array_layout
1909 , typename SrcTraits::device_type
1910 , typename SrcTraits::memory_traits > traits_type ;
1911
1912 typedef Kokkos::View
1913 < data_type
1914 , array_layout
1915 , typename SrcTraits::device_type
1916 , typename SrcTraits::memory_traits > type ;
1917
1918
1919 KOKKOS_INLINE_FUNCTION
1920 static void assign( ViewMapping< traits_type , typename traits_type::specialize > & dst
1921 , ViewMapping< SrcTraits ,typename SrcTraits::specialize > const & src
1922 , Args ... args )
1923 {
1924 typedef ViewMapping< traits_type , typename traits_type::specialize > DstType ;
1925 typedef typename DstType::offset_type dst_offset_type ;
1926 typedef typename DstType::array_offset_type dst_array_offset_type ;
1927 typedef typename DstType::handle_type dst_handle_type ;
1928
1929 const SubviewExtents< SrcTraits::rank , rank >
1930 extents( src.m_impl_offset.m_dim , args... );
1931 const SubviewExtents< SrcTraits::rank + 1 , rank + 1 >
1932 array_extents( src.m_array_offset.m_dim , args... , Kokkos::ALL() );
1933
1934 dst.m_impl_offset = dst_offset_type( src.m_impl_offset , extents );
1935 dst.m_array_offset = dst_array_offset_type( src.m_array_offset , array_extents );
1936 dst.m_impl_handle =
1937 dst_handle_type( src.m_impl_handle +
1938 src.m_array_offset( array_extents.domain_offset(0)
1939 , array_extents.domain_offset(1)
1940 , array_extents.domain_offset(2)
1941 , array_extents.domain_offset(3)
1942 , array_extents.domain_offset(4)
1943 , array_extents.domain_offset(5)
1944 , array_extents.domain_offset(6)
1945 , array_extents.domain_offset(7) ) );
1946 dst.m_fad_size = src.m_fad_size;
1947 dst.m_fad_stride = src.m_fad_stride.value;
1948 }
1949
1950};
1951
1952} // namespace Impl
1953} // namespace Kokkos
1954
1955//----------------------------------------------------------------------------
1956//----------------------------------------------------------------------------
1957
1958#if defined(HAVE_SACADO_KOKKOSCORE) && \
1959 defined(HAVE_SACADO_TEUCHOSKOKKOSCOMM) && \
1960 defined(HAVE_SACADO_VIEW_SPEC) && \
1961 ! defined(SACADO_DISABLE_FAD_VIEW_SPEC)
1962
1963#include "Kokkos_TeuchosCommAdapters.hpp"
1964
1965namespace Teuchos {
1966
1967template< typename Ordinal , class SD , class ... SP , class RD , class ... RP >
1968typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
1969 Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
1970 >::type
1971reduceAll
1972 ( const Comm<Ordinal>& comm,
1973 const EReductionType reductType ,
1974 const Ordinal count,
1975 const Kokkos::View<SD,SP...> & sendBuffer ,
1976 const Kokkos::View<RD,RP...> & recvBuffer )
1977{
1978 // We can't implement reduceAll by extracting the underlying array (since we
1979 // can't reduce across the derivative dimension) and we can't just extract
1980 // a pointer due to ViewFad. In principle we could handle ViewFad in the
1981 // serializer, but for the time being we just copy the view's into local
1982 // buffers (on the host).
1983 typedef Kokkos::View<SD,SP...> SendViewType;
1984 typedef Kokkos::View<RD,RP...> RecvViewType;
1985 typedef typename SendViewType::value_type send_value_type;
1986 typedef typename RecvViewType::value_type recv_value_type;
1987
1988 TEUCHOS_TEST_FOR_EXCEPTION(
1989 SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
1990 "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
1991 "The send View's rank is " << SendViewType::rank << " and the receive "
1992 "View's rank is " << RecvViewType::rank << ".");
1993
1994 // Copy send buffer into local array
1995 Teuchos::Array<send_value_type> localSendBuffer(count);
1996 typename SendViewType::HostMirror hostSendBuffer =
1997 Kokkos::create_mirror_view(sendBuffer);
1998 Kokkos::deep_copy(hostSendBuffer, sendBuffer);
1999 for (Ordinal i=0; i<count; ++i)
2000 localSendBuffer[i] = hostSendBuffer(i);
2001
2002 // Copy receive buffer into local array (necessary to initialize Fad types
2003 // properly)
2004 Teuchos::Array<recv_value_type> localRecvBuffer(count);
2005 typename RecvViewType::HostMirror hostRecvBuffer =
2006 Kokkos::create_mirror_view(recvBuffer);
2007 Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
2008 for (Ordinal i=0; i<count; ++i)
2009 localRecvBuffer[i] = hostRecvBuffer(i);
2010
2011 // Do reduce-all
2012 reduceAll(comm, reductType, count,
2013 localSendBuffer.getRawPtr(),
2014 localRecvBuffer.getRawPtr());
2015
2016 // Copy back into original buffer
2017 for (Ordinal i=0; i<count; ++i)
2018 hostRecvBuffer(i) = localRecvBuffer[i];
2019 Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
2020}
2021
2022
2023template< typename Ordinal , typename Serializer ,
2024 class SD , class ... SP , class RD , class ... RP >
2025typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
2026 Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
2027 >::type
2028reduceAll
2029 ( const Comm<Ordinal>& comm,
2030 const Serializer& serializer,
2031 const EReductionType reductType ,
2032 const Ordinal count,
2033 const Kokkos::View<SD,SP...> & sendBuffer ,
2034 const Kokkos::View<RD,RP...> & recvBuffer )
2035{
2036 // We can't implement reduceAll by extracting the underlying array (since we
2037 // can't reduce across the derivative dimension) and we can't just extract
2038 // a pointer due to ViewFad. In principle we could handle ViewFad in the
2039 // serializer, but for the time being we just copy the view's into local
2040 // buffers (on the host).
2041 typedef Kokkos::View<SD,SP...> SendViewType;
2042 typedef Kokkos::View<RD,RP...> RecvViewType;
2043 typedef typename SendViewType::value_type send_value_type;
2044 typedef typename RecvViewType::value_type recv_value_type;
2045
2046 TEUCHOS_TEST_FOR_EXCEPTION(
2047 SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
2048 "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
2049 "The send View's rank is " << SendViewType::rank << " and the receive " "View's rank is " << RecvViewType::rank << ".");
2050
2051 // Copy send buffer into local array
2052 Teuchos::Array<send_value_type> localSendBuffer(count);
2053 typename SendViewType::HostMirror hostSendBuffer =
2054 Kokkos::create_mirror_view(sendBuffer);
2055 Kokkos::deep_copy(hostSendBuffer, sendBuffer);
2056 for (Ordinal i=0; i<count; ++i)
2057 localSendBuffer[i] = hostSendBuffer(i);
2058
2059 // Copy receive buffer into local array (necessary to initialize Fad types
2060 // properly)
2061 Teuchos::Array<recv_value_type> localRecvBuffer(count);
2062 typename RecvViewType::HostMirror hostRecvBuffer =
2063 Kokkos::create_mirror_view(recvBuffer);
2064 Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
2065 for (Ordinal i=0; i<count; ++i)
2066 localRecvBuffer[i] = hostRecvBuffer(i);
2067
2068 // Do reduce-all
2069 reduceAll(comm, serializer, reductType, count,
2070 localSendBuffer.getRawPtr(),
2071 localRecvBuffer.getRawPtr());
2072
2073 // Copy back into original buffer
2074 for (Ordinal i=0; i<count; ++i)
2075 hostRecvBuffer(i) = localRecvBuffer[i];
2076 Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
2077}
2078
2079
2080template<typename Ordinal, class D, class ... P >
2081typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
2082broadcast
2083 ( const Comm<Ordinal>& comm,
2084 const int rootRank ,
2085 const Ordinal count,
2086 const Kokkos::View<D,P...>& buffer)
2087{
2088 typedef Kokkos::View<D,P...> view_type;
2089 typename view_type::array_type array_buffer = buffer;
2090 Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
2091 broadcast( comm, rootRank, array_count, array_buffer );
2092}
2093
2094template<typename Ordinal,
2095 typename Serializer ,
2096 class D, class ... P >
2097typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
2098broadcast
2099 ( const Comm<Ordinal>& comm,
2100 const Serializer& serializer,
2101 const int rootRank ,
2102 const Ordinal count,
2103 const Kokkos::View<D,P...>& buffer)
2104{
2105 typedef Kokkos::View<D,P...> view_type;
2106 typename view_type::array_type array_buffer = buffer;
2107 Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
2108 broadcast( comm, *(serializer.getValueSerializer()), rootRank,
2109 array_count, array_buffer );
2110}
2111
2112} // namespace Teuchos
2113
2114#endif
2115
2116//----------------------------------------------------------------------------
2117
2118#endif // defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
2119
2120#endif // defined(HAVE_SACADO_KOKKOSCORE)
2121
2123
2124#endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_SACADO_FAD_HPP */
int Ordinal
View
expr expr expr bar false
expr true
#define T
#define A
#define D
const int N
const int fad_dim
Forward-mode AD class templated on the storage for the derivative array.
Namespace for forward-mode AD classes w/caching.
Namespace for expression-level reverse forward-mode AD classes.
Namespace for expression-level reverse forward-mode AD classes.
Namespace for forward-mode AD classes.
static const bool value
static const unsigned value