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_KOKKOS)
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 auto space = ((ViewCtorProp<void,execution_space> const &) prop).value;
1525 // Assume destruction is only required when construction is requested.
1526 // The ViewValueFunctor has both value construction and destruction operators.
1527 if (execution_space_specified)
1528 record->m_destroy = functor_type( space
1529 , (fad_value_type *) m_impl_handle
1530 , m_array_offset.span()
1531 , record->get_label()
1532 );
1533 else
1534 record->m_destroy = functor_type((fad_value_type *) m_impl_handle
1535 , m_array_offset.span()
1536 , record->get_label()
1537 );
1538
1539 // Construct values
1540 record->m_destroy.construct_shared_allocation();
1541 space.fence();
1542 }
1543 }
1544
1545 return record ;
1546 }
1547
1548};
1549
1550} // namespace Impl
1551} // namespace Kokkos
1552
1553//----------------------------------------------------------------------------
1554
1555namespace Kokkos {
1556namespace Impl {
1557
1562template< class DstTraits , class SrcTraits >
1563class ViewMapping< DstTraits , SrcTraits ,
1564 typename std::enable_if<(
1565 Kokkos::Impl::MemorySpaceAccess
1566 < typename DstTraits::memory_space
1567 , typename SrcTraits::memory_space >::assignable
1568 &&
1569 // Destination view has FAD
1570 std::is_same< typename DstTraits::specialize
1571 , ViewSpecializeSacadoFad >::value
1572 &&
1573 // Source view has FAD
1574 std::is_same< typename SrcTraits::specialize
1575 , ViewSpecializeSacadoFad >::value
1576
1577 )
1578 , typename DstTraits::specialize
1579 >::type >
1580{
1581public:
1582
1583 enum { is_assignable = true };
1584 enum { is_assignable_data_type = true };
1585
1586 typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1587 typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1588 typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1589
1590 template< class DstType >
1591 KOKKOS_INLINE_FUNCTION static
1592 void assign( DstType & dst
1593 , const SrcFadType & src
1594 , const TrackType & )
1595 {
1596 static_assert(
1597 (
1598 std::is_same< typename DstTraits::array_layout
1599 , Kokkos::LayoutLeft >::value ||
1600 std::is_same< typename DstTraits::array_layout
1601 , Kokkos::LayoutRight >::value ||
1602 std::is_same< typename DstTraits::array_layout
1603 , Kokkos::LayoutStride >::value
1604 )
1605 &&
1606 (
1607 std::is_same< typename SrcTraits::array_layout
1608 , Kokkos::LayoutLeft >::value ||
1609 std::is_same< typename SrcTraits::array_layout
1610 , Kokkos::LayoutRight >::value ||
1611 std::is_same< typename SrcTraits::array_layout
1612 , Kokkos::LayoutStride >::value
1613 )
1614 , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1615
1616 static_assert(
1617 std::is_same< typename DstTraits::array_layout
1618 , typename SrcTraits::array_layout >::value ||
1619 std::is_same< typename DstTraits::array_layout
1620 , Kokkos::LayoutStride >::value ,
1621 "View assignment must have compatible layout" );
1622
1623 static_assert(
1624 std::is_same< typename DstTraits::value_type
1625 , typename SrcTraits::value_type >::value ||
1626 std::is_same< typename DstTraits::value_type
1627 , typename SrcTraits::const_value_type >::value ,
1628 "View assignment must have same value type or const = non-const" );
1629
1630 static_assert(
1631 ViewDimensionAssignable
1632 < typename DstType::offset_type::dimension_type
1633 , typename SrcFadType::offset_type::dimension_type >::value ,
1634 "View assignment must have compatible dimensions" );
1635
1636 static_assert(
1637 ViewDimensionAssignable
1638 < typename DstType::array_offset_type::dimension_type
1639 , typename SrcFadType::array_offset_type::dimension_type >::value ,
1640 "View assignment must have compatible dimensions" );
1641
1642 typedef typename DstType::offset_type dst_offset_type ;
1643 typedef typename DstType::array_offset_type dst_array_offset_type ;
1644
1645 dst.m_impl_handle = src.m_impl_handle ;
1646 dst.m_impl_offset = dst_offset_type( src.m_impl_offset );
1647 dst.m_array_offset = dst_array_offset_type( src.m_array_offset );
1648 dst.m_fad_size = src.m_fad_size.value ;
1649 dst.m_fad_stride = src.m_fad_stride.value ;
1650 }
1651};
1652
1653// Integer argument is the actual rank => ranks 0 to Rank-1 will be assigned
1659template< class DstTraits , class SrcTraits >
1660class ViewMapping< DstTraits , SrcTraits ,
1661 typename std::enable_if<(
1662 Kokkos::Impl::MemorySpaceAccess
1663 < typename DstTraits::memory_space
1664 , typename SrcTraits::memory_space >::assignable
1665 &&
1666 // Destination view has ordinary
1667 std::is_same< typename DstTraits::specialize , void >::value
1668 &&
1669 // Source view has FAD only
1670 std::is_same< typename SrcTraits::specialize
1671 , ViewSpecializeSacadoFad >::value
1672 )
1673 , typename DstTraits::specialize
1674 >::type >
1675{
1676public:
1677
1678 enum { is_assignable = true };
1679 enum { is_assignable_data_type = true };
1680
1681
1682 typedef Kokkos::Impl::SharedAllocationTracker TrackType ;
1683 typedef ViewMapping< DstTraits , typename DstTraits::specialize > DstType ;
1684 typedef ViewMapping< SrcTraits , typename SrcTraits::specialize > SrcFadType ;
1685
1686
1687 // Helpers to assign, and generate if necessary, ViewOffset to the dst map
1688 // These are necessary to use Kokkos' deep_copy with nested fads
1689 template < class DstType, class SrcFadType, class Truth = void >
1690 struct AssignOffset;
1691
1692 template < class DstType, class SrcFadType >
1693 struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank != (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
1694 {
1695 // ViewOffset's Dimensions Ranks do not match
1696 KOKKOS_INLINE_FUNCTION
1697 static void assign( DstType & dst, const SrcFadType & src )
1698 {
1699 typedef typename SrcTraits::value_type TraitsValueType;
1700
1702 && Sacado::IsStaticallySized< typename Sacado::ValueType< TraitsValueType >::type >::value
1703 )
1704 {
1705 typedef typename DstType::offset_type::array_layout DstLayoutType;
1706 //typedef typename ViewArrayLayoutSelector<typename DstType::offset_type::array_layout>::type DstLayoutType;
1707 typedef typename SrcFadType::array_offset_type::dimension_type SrcViewDimension;
1708
1709 // This is the static dimension of the inner fad, missing from ViewDimension
1710 const size_t InnerStaticDim = Sacado::StaticSize< typename Sacado::ValueType< TraitsValueType >::type >::value;
1711
1712 static constexpr bool is_layout_left =
1713 std::is_same< DstLayoutType, Kokkos::LayoutLeft>::value;
1714
1715 typedef typename std::conditional< is_layout_left,
1716 typename SrcViewDimension:: template prepend< InnerStaticDim+1 >::type,
1717 typename SrcViewDimension:: template append < InnerStaticDim+1 >::type
1718 >::type SrcViewDimensionAppended;
1719
1720 typedef std::integral_constant< unsigned , 0 > padding ;
1721
1722 typedef ViewOffset< SrcViewDimensionAppended, DstLayoutType > TmpOffsetType;
1723
1724 auto src_layout = src.m_array_offset.layout();
1725
1726 if ( is_layout_left ) {
1727 auto prepend_layout = Kokkos::Impl::prependFadToLayout< DstLayoutType >::returnNewLayoutPlusFad(src_layout, InnerStaticDim+1);
1728 TmpOffsetType offset_tmp( padding(), prepend_layout );
1729 dst.m_impl_offset = offset_tmp;
1730 }
1731 else {
1732 TmpOffsetType offset_tmp( padding(), src_layout );
1733 dst.m_impl_offset = offset_tmp;
1734 }
1735
1736 } else {
1737 Kokkos::abort("Sacado error: Applying AssignOffset for case with nested Fads, but without nested Fads - something went wrong");
1738 }
1739 }
1740 };
1741
1742 template < class DstType, class SrcFadType >
1743 struct AssignOffset< DstType, SrcFadType, typename std::enable_if< ((int)DstType::offset_type::dimension_type::rank == (int)SrcFadType::array_offset_type::dimension_type::rank) >::type >
1744 {
1745 KOKKOS_INLINE_FUNCTION
1746 static void assign( DstType & dst, const SrcFadType & src )
1747 {
1748
1749 typedef typename DstType::offset_type dst_offset_type ;
1750 dst.m_impl_offset = dst_offset_type( src.m_array_offset );
1751 }
1752 };
1753
1754
1755// If the dst and src mappings are not equal in Rank, the src should come from a View of nested fads
1756// In the case of two nested fads, the innermost must be an SFad (static Fad)
1757// The offset_type's are not compatible in the case of nested fads because the ViewDimension's ranks will not agree
1758// In this case, rather than trying to construct an offset_type from src (which will fail at compile time)
1759// and assign to dst.m_impl_offset, manually assign the ViewDimension arguments to dst;
1760// requires appending the missing inner SFad dim + 1 to the Rank-1 ViewDimension
1761 // DstType and SrcFadType are MAPS...
1762 template < class DstType >
1763 KOKKOS_INLINE_FUNCTION static
1764 void
1765 assign( DstType & dst
1766 , const SrcFadType & src
1767 , const TrackType &
1768 )
1769 {
1770
1771 static_assert(
1772 (
1773 std::is_same< typename DstTraits::array_layout
1774 , Kokkos::LayoutLeft >::value ||
1775 std::is_same< typename DstTraits::array_layout
1776 , Kokkos::LayoutRight >::value ||
1777 std::is_same< typename DstTraits::array_layout
1778 , Kokkos::LayoutStride >::value
1779 )
1780 &&
1781 (
1782 std::is_same< typename SrcTraits::array_layout
1783 , Kokkos::LayoutLeft >::value ||
1784 std::is_same< typename SrcTraits::array_layout
1785 , Kokkos::LayoutRight >::value ||
1786 std::is_same< typename SrcTraits::array_layout
1787 , Kokkos::LayoutStride >::value
1788 )
1789 , "View of FAD requires LayoutLeft, LayoutRight, or LayoutStride" );
1790
1791 static_assert(
1792 std::is_same< typename DstTraits::array_layout
1793 , typename SrcTraits::array_layout >::value ||
1794 std::is_same< typename DstTraits::array_layout
1795 , Kokkos::LayoutStride >::value ,
1796 "View assignment must have compatible layout" );
1797#if 0
1798 static_assert(
1799 std::is_same< typename DstTraits::scalar_array_type
1800 , typename SrcTraits::scalar_array_type >::value ||
1801 std::is_same< typename DstTraits::scalar_array_type
1802 , typename SrcTraits::const_scalar_array_type >::value ,
1803 "View assignment must have same value type or const = non-const" );
1804#endif
1805
1806 AssignOffset< DstType, SrcFadType >::assign( dst, src );
1807
1808 dst.m_impl_handle = reinterpret_cast< typename DstType::handle_type >(src.m_impl_handle) ;
1809 }
1810};
1811
1812} // namespace Impl
1813} // namespace Kokkos
1814
1815//----------------------------------------------------------------------------
1816
1817namespace Kokkos {
1818namespace Impl {
1819
1820// Subview mapping
1821
1822template< class SrcTraits , class ... Args >
1823struct ViewMapping
1824 < typename std::enable_if<(
1825 // Source view has FAD only
1826 std::is_same< typename SrcTraits::specialize
1827 , ViewSpecializeSacadoFad >::value
1828 &&
1829 (
1830 std::is_same< typename SrcTraits::array_layout
1831 , Kokkos::LayoutLeft >::value ||
1832 std::is_same< typename SrcTraits::array_layout
1833 , Kokkos::LayoutRight >::value ||
1834 std::is_same< typename SrcTraits::array_layout
1835 , Kokkos::LayoutStride >::value
1836 )
1837 )
1838 >::type
1839 , SrcTraits
1840 , Args ... >
1841{
1842private:
1843
1844 static_assert( SrcTraits::rank == sizeof...(Args) , "" );
1845
1846 enum
1847 { RZ = false
1848 , R0 = bool(is_integral_extent<0,Args...>::value)
1849 , R1 = bool(is_integral_extent<1,Args...>::value)
1850 , R2 = bool(is_integral_extent<2,Args...>::value)
1851 , R3 = bool(is_integral_extent<3,Args...>::value)
1852 , R4 = bool(is_integral_extent<4,Args...>::value)
1853 , R5 = bool(is_integral_extent<5,Args...>::value)
1854 , R6 = bool(is_integral_extent<6,Args...>::value)
1855 };
1856
1857 // Public rank
1858 enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
1859 + unsigned(R4) + unsigned(R5) + unsigned(R6) };
1860
1861 // Whether right-most non-FAD rank is a range.
1862 enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
1863 1 == SrcTraits::rank ? R0 : (
1864 2 == SrcTraits::rank ? R1 : (
1865 3 == SrcTraits::rank ? R2 : (
1866 4 == SrcTraits::rank ? R3 : (
1867 5 == SrcTraits::rank ? R4 : (
1868 6 == SrcTraits::rank ? R5 : R6 ))))))) };
1869
1870 // Subview's layout
1871 // If LayoutRight then FAD is contiguous
1872 // For LayoutLeft, result is LayoutLeft only if 1st arg is a range,
1873 // and since last (FAD) dimension is also a range, and these
1874 // ranges must be consecutive, the input rank must be 1
1875 typedef typename std::conditional<
1876 ( /* Same layout IF */
1877 ( rank == 0 )
1878 ||
1879 ( std::is_same< typename SrcTraits::array_layout
1880 , Kokkos::LayoutRight >::value
1881 &&
1882 ( rank == 1 ) && R0_rev
1883 )
1884 ||
1885 ( std::is_same< typename SrcTraits::array_layout
1886 , Kokkos::LayoutLeft >::value
1887 &&
1888 ( rank == 1 ) && (SrcTraits::rank == 1) && R0
1889 )
1890 ), typename SrcTraits::array_layout , Kokkos::LayoutStride
1891 >::type array_layout ;
1892
1893 typedef typename SrcTraits::value_type fad_type ;
1894
1895 typedef typename std::conditional< rank == 0 , fad_type ,
1896 typename std::conditional< rank == 1 , fad_type * ,
1897 typename std::conditional< rank == 2 , fad_type ** ,
1898 typename std::conditional< rank == 3 , fad_type *** ,
1899 typename std::conditional< rank == 4 , fad_type **** ,
1900 typename std::conditional< rank == 5 , fad_type ***** ,
1901 typename std::conditional< rank == 6 , fad_type ****** ,
1902 fad_type *******
1903 >::type >::type >::type >::type >::type >::type >::type
1904 data_type ;
1905
1906public:
1907
1908 typedef Kokkos::ViewTraits
1909 < data_type
1910 , array_layout
1911 , typename SrcTraits::device_type
1912 , typename SrcTraits::memory_traits > traits_type ;
1913
1914 typedef Kokkos::View
1915 < data_type
1916 , array_layout
1917 , typename SrcTraits::device_type
1918 , typename SrcTraits::memory_traits > type ;
1919
1920
1921 KOKKOS_INLINE_FUNCTION
1922 static void assign( ViewMapping< traits_type , typename traits_type::specialize > & dst
1923 , ViewMapping< SrcTraits ,typename SrcTraits::specialize > const & src
1924 , Args ... args )
1925 {
1926 typedef ViewMapping< traits_type , typename traits_type::specialize > DstType ;
1927 typedef typename DstType::offset_type dst_offset_type ;
1928 typedef typename DstType::array_offset_type dst_array_offset_type ;
1929 typedef typename DstType::handle_type dst_handle_type ;
1930
1931 const SubviewExtents< SrcTraits::rank , rank >
1932 extents( src.m_impl_offset.m_dim , args... );
1933 const SubviewExtents< SrcTraits::rank + 1 , rank + 1 >
1934 array_extents( src.m_array_offset.m_dim , args... , Kokkos::ALL() );
1935
1936 dst.m_impl_offset = dst_offset_type( src.m_impl_offset , extents );
1937 dst.m_array_offset = dst_array_offset_type( src.m_array_offset , array_extents );
1938 dst.m_impl_handle =
1939 dst_handle_type( src.m_impl_handle +
1940 src.m_array_offset( array_extents.domain_offset(0)
1941 , array_extents.domain_offset(1)
1942 , array_extents.domain_offset(2)
1943 , array_extents.domain_offset(3)
1944 , array_extents.domain_offset(4)
1945 , array_extents.domain_offset(5)
1946 , array_extents.domain_offset(6)
1947 , array_extents.domain_offset(7) ) );
1948 dst.m_fad_size = src.m_fad_size;
1949 dst.m_fad_stride = src.m_fad_stride.value;
1950 }
1951
1952};
1953
1954} // namespace Impl
1955} // namespace Kokkos
1956
1957//----------------------------------------------------------------------------
1958//----------------------------------------------------------------------------
1959
1960#if defined(HAVE_SACADO_KOKKOS) && \
1961 defined(HAVE_SACADO_TEUCHOSKOKKOSCOMM) && \
1962 defined(HAVE_SACADO_VIEW_SPEC) && \
1963 ! defined(SACADO_DISABLE_FAD_VIEW_SPEC)
1964
1965#include "Kokkos_TeuchosCommAdapters.hpp"
1966
1967namespace Teuchos {
1968
1969template< typename Ordinal , class SD , class ... SP , class RD , class ... RP >
1970typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
1971 Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
1972 >::type
1973reduceAll
1974 ( const Comm<Ordinal>& comm,
1975 const EReductionType reductType ,
1976 const Ordinal count,
1977 const Kokkos::View<SD,SP...> & sendBuffer ,
1978 const Kokkos::View<RD,RP...> & recvBuffer )
1979{
1980 // We can't implement reduceAll by extracting the underlying array (since we
1981 // can't reduce across the derivative dimension) and we can't just extract
1982 // a pointer due to ViewFad. In principle we could handle ViewFad in the
1983 // serializer, but for the time being we just copy the view's into local
1984 // buffers (on the host).
1985 typedef Kokkos::View<SD,SP...> SendViewType;
1986 typedef Kokkos::View<RD,RP...> RecvViewType;
1987 typedef typename SendViewType::value_type send_value_type;
1988 typedef typename RecvViewType::value_type recv_value_type;
1989
1990 TEUCHOS_TEST_FOR_EXCEPTION(
1991 SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
1992 "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
1993 "The send View's rank is " << SendViewType::rank << " and the receive "
1994 "View's rank is " << RecvViewType::rank << ".");
1995
1996 // Copy send buffer into local array
1997 Teuchos::Array<send_value_type> localSendBuffer(count);
1998 typename SendViewType::HostMirror hostSendBuffer =
1999 Kokkos::create_mirror_view(sendBuffer);
2000 Kokkos::deep_copy(hostSendBuffer, sendBuffer);
2001 for (Ordinal i=0; i<count; ++i)
2002 localSendBuffer[i] = hostSendBuffer(i);
2003
2004 // Copy receive buffer into local array (necessary to initialize Fad types
2005 // properly)
2006 Teuchos::Array<recv_value_type> localRecvBuffer(count);
2007 typename RecvViewType::HostMirror hostRecvBuffer =
2008 Kokkos::create_mirror_view(recvBuffer);
2009 Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
2010 for (Ordinal i=0; i<count; ++i)
2011 localRecvBuffer[i] = hostRecvBuffer(i);
2012
2013 // Do reduce-all
2014 reduceAll(comm, reductType, count,
2015 localSendBuffer.getRawPtr(),
2016 localRecvBuffer.getRawPtr());
2017
2018 // Copy back into original buffer
2019 for (Ordinal i=0; i<count; ++i)
2020 hostRecvBuffer(i) = localRecvBuffer[i];
2021 Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
2022}
2023
2024
2025template< typename Ordinal , typename Serializer ,
2026 class SD , class ... SP , class RD , class ... RP >
2027typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<SD,SP...> >::value &&
2028 Kokkos::is_view_fad< Kokkos::View<RD,RP...> >::value
2029 >::type
2030reduceAll
2031 ( const Comm<Ordinal>& comm,
2032 const Serializer& serializer,
2033 const EReductionType reductType ,
2034 const Ordinal count,
2035 const Kokkos::View<SD,SP...> & sendBuffer ,
2036 const Kokkos::View<RD,RP...> & recvBuffer )
2037{
2038 // We can't implement reduceAll by extracting the underlying array (since we
2039 // can't reduce across the derivative dimension) and we can't just extract
2040 // a pointer due to ViewFad. In principle we could handle ViewFad in the
2041 // serializer, but for the time being we just copy the view's into local
2042 // buffers (on the host).
2043 typedef Kokkos::View<SD,SP...> SendViewType;
2044 typedef Kokkos::View<RD,RP...> RecvViewType;
2045 typedef typename SendViewType::value_type send_value_type;
2046 typedef typename RecvViewType::value_type recv_value_type;
2047
2048 TEUCHOS_TEST_FOR_EXCEPTION(
2049 SendViewType::rank > 1 || RecvViewType::rank > 1, std::invalid_argument,
2050 "Teuchos::reduceAll: Both send and receive Views must have rank 1. "
2051 "The send View's rank is " << SendViewType::rank << " and the receive " "View's rank is " << RecvViewType::rank << ".");
2052
2053 // Copy send buffer into local array
2054 Teuchos::Array<send_value_type> localSendBuffer(count);
2055 typename SendViewType::HostMirror hostSendBuffer =
2056 Kokkos::create_mirror_view(sendBuffer);
2057 Kokkos::deep_copy(hostSendBuffer, sendBuffer);
2058 for (Ordinal i=0; i<count; ++i)
2059 localSendBuffer[i] = hostSendBuffer(i);
2060
2061 // Copy receive buffer into local array (necessary to initialize Fad types
2062 // properly)
2063 Teuchos::Array<recv_value_type> localRecvBuffer(count);
2064 typename RecvViewType::HostMirror hostRecvBuffer =
2065 Kokkos::create_mirror_view(recvBuffer);
2066 Kokkos::deep_copy(hostRecvBuffer, recvBuffer);
2067 for (Ordinal i=0; i<count; ++i)
2068 localRecvBuffer[i] = hostRecvBuffer(i);
2069
2070 // Do reduce-all
2071 reduceAll(comm, serializer, reductType, count,
2072 localSendBuffer.getRawPtr(),
2073 localRecvBuffer.getRawPtr());
2074
2075 // Copy back into original buffer
2076 for (Ordinal i=0; i<count; ++i)
2077 hostRecvBuffer(i) = localRecvBuffer[i];
2078 Kokkos::deep_copy(recvBuffer, hostRecvBuffer);
2079}
2080
2081
2082template<typename Ordinal, class D, class ... P >
2083typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
2084broadcast
2085 ( const Comm<Ordinal>& comm,
2086 const int rootRank ,
2087 const Ordinal count,
2088 const Kokkos::View<D,P...>& buffer)
2089{
2090 typedef Kokkos::View<D,P...> view_type;
2091 typename view_type::array_type array_buffer = buffer;
2092 Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
2093 broadcast( comm, rootRank, array_count, array_buffer );
2094}
2095
2096template<typename Ordinal,
2097 typename Serializer ,
2098 class D, class ... P >
2099typename std::enable_if<Kokkos::is_view_fad< Kokkos::View<D,P...> >::value>::type
2100broadcast
2101 ( const Comm<Ordinal>& comm,
2102 const Serializer& serializer,
2103 const int rootRank ,
2104 const Ordinal count,
2105 const Kokkos::View<D,P...>& buffer)
2106{
2107 typedef Kokkos::View<D,P...> view_type;
2108 typename view_type::array_type array_buffer = buffer;
2109 Ordinal array_count = count * Kokkos::dimension_scalar(buffer);
2110 broadcast( comm, *(serializer.getValueSerializer()), rootRank,
2111 array_count, array_buffer );
2112}
2113
2114} // namespace Teuchos
2115
2116#endif
2117
2118//----------------------------------------------------------------------------
2119
2120#endif // defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC)
2121
2122#endif // defined(HAVE_SACADO_KOKKOS)
2123
2125
2126#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