Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
KokkosExp_View_UQ_PCE_Contiguous.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef KOKKOS_EXPERIMENTAL_VIEW_UQ_PCE_CONTIGUOUS_HPP
43 #define KOKKOS_EXPERIMENTAL_VIEW_UQ_PCE_CONTIGUOUS_HPP
44 
45 #include "Sacado_Traits.hpp"
46 #include "Sacado_UQ_PCE.hpp"
47 #include "Sacado_UQ_PCE_Traits.hpp"
48 
49 #include "Kokkos_Core.hpp"
51 #include "Kokkos_View_Utils.hpp"
53 
54 #include "impl/KokkosExp_ViewMapping.hpp"
55 
56 //----------------------------------------------------------------------------
57 
58 namespace Kokkos {
59 namespace Experimental {
60 namespace Impl {
61 
63 
64 template< class ... Args >
65 struct is_ViewPCEContiguous { enum { value = false }; };
66 
67 template< class D , class ... P , class ... Args >
68 struct is_ViewPCEContiguous< Kokkos::View<D,P...> , Args... > {
69  enum { value =
70  std::is_same< typename Kokkos::ViewTraits<D,P...>::specialize
72  &&
73  ( ( sizeof...(Args) == 0 ) ||
74  is_ViewPCEContiguous< Args... >::value ) };
75 };
76 
77 } // namespace Impl
78 } // namespace Experimental
79 } // namespace Kokkos
80 
81 namespace Kokkos {
82 
83 // Overload of deep_copy for UQ::PCE views intializing to a constant scalar
84 template< class DT, class ... DP >
85 void deep_copy(
86  const View<DT,DP...> & view ,
87  const typename View<DT,DP...>::array_type::value_type & value
88  , typename std::enable_if<(
89  std::is_same< typename ViewTraits<DT,DP...>::specialize
91  )>::type * = 0 )
92 {
93  static_assert(
94  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
95  typename ViewTraits<DT,DP...>::non_const_value_type >::value
96  , "Can only deep copy into non-const type" );
97 
98  typedef View<DT,DP...> view_type;
100  typedef typename FlatArrayType<view_type>::type flat_array_type;
101  if (value == scalar_type(0))
102  Kokkos::Experimental::Impl::ViewFill< flat_array_type >( view , value );
103  else
104  Kokkos::Experimental::Impl::ViewFill< view_type>( view , value );
105 }
106 
107 // Overload of deep_copy for UQ::PCE views intializing to a constant UQ::PCE
108 template< class DT, class ... DP >
110  const View<DT,DP...> & view ,
111  const typename View<DT,DP...>::value_type & value
112  , typename std::enable_if<(
113  std::is_same< typename ViewTraits<DT,DP...>::specialize
115  )>::type * = 0 )
116 {
117  static_assert(
118  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
119  typename ViewTraits<DT,DP...>::non_const_value_type >::value
120  , "Can only deep copy into non-const type" );
121 
122  Kokkos::Experimental::Impl::ViewFill< View<DT,DP...> >( view , value );
123 }
124 
125 namespace Experimental {
126 namespace Impl {
127 
128 // Deep copy between views not assuming contiguous storage of arrays
129 // Need to use team interface for Cuda
130 template< class OutputView , class InputView >
132 {
134  typedef typename execution_space::size_type size_type ;
135 
136  const OutputView output ;
137  const InputView input ;
138 
139  DeepCopyNonContiguous( const OutputView & arg_out ,
140  const InputView & arg_in ) :
141  output( arg_out ), input( arg_in )
142  {
143  parallel_for( output.dimension_0() , *this );
144  execution_space::fence();
145  }
146 
147  KOKKOS_INLINE_FUNCTION
148  void operator()( const size_type i0 ) const
149  {
150  for ( size_type i1 = 0 ; i1 < output.dimension_1() ; ++i1 ) {
151  for ( size_type i2 = 0 ; i2 < output.dimension_2() ; ++i2 ) {
152  for ( size_type i3 = 0 ; i3 < output.dimension_3() ; ++i3 ) {
153  for ( size_type i4 = 0 ; i4 < output.dimension_4() ; ++i4 ) {
154  for ( size_type i5 = 0 ; i5 < output.dimension_5() ; ++i5 ) {
155  for ( size_type i6 = 0 ; i6 < output.dimension_6() ; ++i6 ) {
156  for ( size_type i7 = 0 ; i7 < output.dimension_7() ; ++i7 ) {
157  output(i0,i1,i2,i3,i4,i5,i6,i7) = input(i0,i1,i2,i3,i4,i5,i6,i7) ;
158  }}}}}}}
159  }
160 };
161 
162 } // namespace Impl
163 } // namespace Experimental
164 
165 /* Specialize for deep copy of UQ::PCE */
166 template< class DT , class ... DP , class ST , class ... SP >
167 inline
168 void deep_copy( const View<DT,DP...> & dst ,
169  const View<ST,SP...> & src
170  , typename std::enable_if<(
171  std::is_same< typename ViewTraits<DT,DP...>::specialize
173  &&
174  std::is_same< typename ViewTraits<ST,SP...>::specialize
176  )>::type * = 0 )
177 {
178  static_assert(
179  std::is_same< typename ViewTraits<DT,DP...>::value_type ,
180  typename ViewTraits<DT,DP...>::non_const_value_type >::value
181  , "Deep copy destination must be non-const" );
182 
183  static_assert(
184  ( unsigned(ViewTraits<DT,DP...>::rank) ==
185  unsigned(ViewTraits<ST,SP...>::rank) )
186  , "Deep copy destination and source must have same rank" );
187 
188  typedef View<DT,DP...> dst_type ;
189  typedef View<ST,SP...> src_type ;
190  typedef typename dst_type::array_type dst_array_type ;
191  typedef typename src_type::array_type src_array_type ;
192 
194  dst_array_type dst_array = dst ;
195  src_array_type src_array = src ;
196  deep_copy( dst_array , src_array );
197  }
198 
199  // otherwise, use a custom kernel
200  else {
201 
202  // If views are in the same memory space, copy component-wise
203  if ( Impl::is_same< typename dst_type::memory_space ,
204  typename src_type::memory_space >::value ) {
206  }
207 
208  else {
209 
210  typedef View< typename src_type::non_const_data_type ,
211  typename src_type::array_layout ,
212  typename src_type::execution_space > tmp_src_type;
213  typedef typename tmp_src_type::array_type tmp_src_array_type;
214  typedef View< typename dst_type::non_const_data_type ,
215  typename dst_type::array_layout ,
216  typename dst_type::execution_space > tmp_dst_type;
217  typedef typename tmp_dst_type::array_type tmp_dst_array_type;
218 
219  // Copy src into a contiguous view in src's memory space,
220  // then copy to dst
221  if ( is_allocation_contiguous(dst) &&
222  !is_allocation_contiguous(src) ) {
223  size_t src_dims[8];
224  //src.dimensions(src_dims);
225  src_dims[0] = src.dimension_0();
226  src_dims[1] = src.dimension_1();
227  src_dims[2] = src.dimension_2();
228  src_dims[3] = src.dimension_3();
229  src_dims[4] = src.dimension_4();
230  src_dims[5] = src.dimension_5();
231  src_dims[6] = src.dimension_6();
232  src_dims[7] = src.dimension_7();
233  src_dims[src_type::Rank] = dimension_scalar(src);
234  tmp_src_type src_tmp(
235  Experimental::view_alloc("src_tmp" , Experimental::WithoutInitializing, cijk(src) ) ,
236  src_dims[0], src_dims[1], src_dims[2], src_dims[3],
237  src_dims[4], src_dims[5], src_dims[6], src_dims[7] );
239  dst_array_type dst_array = dst ;
240  tmp_src_array_type src_array = src_tmp ;
241  deep_copy( dst_array , src_array );
242  }
243 
244  // Copy src into a contiguous view in dst's memory space,
245  // then copy to dst
246  else if ( !is_allocation_contiguous(dst) &&
247  is_allocation_contiguous(src) ) {
248  size_t dst_dims[8];
249  //dst.dimensions(dst_dims);
250  dst_dims[0] = dst.dimension_0();
251  dst_dims[1] = dst.dimension_1();
252  dst_dims[2] = dst.dimension_2();
253  dst_dims[3] = dst.dimension_3();
254  dst_dims[4] = dst.dimension_4();
255  dst_dims[5] = dst.dimension_5();
256  dst_dims[6] = dst.dimension_6();
257  dst_dims[7] = dst.dimension_7();
258  dst_dims[dst_type::Rank] = dimension_scalar(dst);
259  tmp_dst_type dst_tmp(
260  Experimental::view_alloc("dst_tmp" , Experimental::WithoutInitializing, cijk(dst) ) ,
261  dst_dims[0], dst_dims[1], dst_dims[2], dst_dims[3],
262  dst_dims[4], dst_dims[5], dst_dims[6], dst_dims[7] );
263  tmp_dst_array_type dst_array = dst_tmp ;
264  src_array_type src_array = src ;
265  deep_copy( dst_array , src_array );
267  }
268 
269  // Copy src into a contiguous view in src's memory space,
270  // copy to a continugous view in dst's memory space, then copy to dst
271  else {
272  size_t src_dims[8];
273  //src.dimensions(src_dims);
274  src_dims[0] = src.dimension_0();
275  src_dims[1] = src.dimension_1();
276  src_dims[2] = src.dimension_2();
277  src_dims[3] = src.dimension_3();
278  src_dims[4] = src.dimension_4();
279  src_dims[5] = src.dimension_5();
280  src_dims[6] = src.dimension_6();
281  src_dims[7] = src.dimension_7();
282  src_dims[src_type::Rank] = dimension_scalar(src);
283  tmp_src_type src_tmp(
284  Experimental::view_alloc("src_tmp" , Experimental::WithoutInitializing, cijk(src) ) ,
285  src_dims[0], src_dims[1], src_dims[2], src_dims[3],
286  src_dims[4], src_dims[5], src_dims[6], src_dims[7] );
288  size_t dst_dims[8];
289  //dst.dimensions(dst_dims);
290  dst_dims[0] = dst.dimension_0();
291  dst_dims[1] = dst.dimension_1();
292  dst_dims[2] = dst.dimension_2();
293  dst_dims[3] = dst.dimension_3();
294  dst_dims[4] = dst.dimension_4();
295  dst_dims[5] = dst.dimension_5();
296  dst_dims[6] = dst.dimension_6();
297  dst_dims[7] = dst.dimension_7();
298  dst_dims[dst_type::Rank] = dimension_scalar(dst);
299  tmp_dst_type dst_tmp(
300  Experimental::view_alloc("dst_tmp" , Experimental::WithoutInitializing, cijk(dst) ) ,
301  dst_dims[0], dst_dims[1], dst_dims[2], dst_dims[3],
302  dst_dims[4], dst_dims[5], dst_dims[6], dst_dims[7] );
303  tmp_dst_array_type dst_array = dst_tmp ;
304  tmp_src_array_type src_array = src_tmp ;
305  deep_copy( dst_array , src_array );
307  }
308  }
309  }
310 }
311 
312 template <typename T, typename ... P>
313 struct is_view_uq_pce< View<T,P...> > {
314  typedef View<T,P...> view_type;
315  static const bool value =
316  std::is_same< typename view_type::specialize,
318 };
319 
320 template <typename D, typename ... P>
321 struct FlatArrayType< View<D,P...>,
322  typename std::enable_if< is_view_uq_pce< View<D,P...> >::value >::type > {
323  typedef View<D,P...> view_type;
324  typedef typename view_type::traits::dimension dimension;
326  typedef typename Kokkos::Experimental::Impl::ViewDataType< flat_value_type , dimension >::type flat_data_type;
327  typedef View<flat_data_type,P...> type;
328 };
329 
330 template <typename ViewType>
331 struct CijkType< ViewType,
332  typename std::enable_if< is_view_uq_pce< ViewType >::value >::type > {
333  typedef typename ViewType::non_const_value_type::cijk_type type;
334 };
335 
336 template <typename T, typename ... P>
337 KOKKOS_INLINE_FUNCTION
338 constexpr typename
339 std::enable_if< is_view_uq_pce< View<T,P...> >::value, unsigned >::type
340 dimension_scalar(const View<T,P...>& view) {
341  return view.implementation_map().dimension_scalar();
342 }
343 
344 template <typename view_type>
345 KOKKOS_INLINE_FUNCTION
346 constexpr typename
347 std::enable_if< is_view_uq_pce<view_type>::value,
348  typename CijkType<view_type>::type >::type
349 cijk(const view_type& view) {
350  return view.implementation_map().cijk();
351 }
352 
353 template <typename view_type>
354 KOKKOS_INLINE_FUNCTION
355 constexpr typename
356 std::enable_if< is_view_uq_pce<view_type>::value, bool >::type
357 is_allocation_contiguous(const view_type& view) {
358  return view.implementation_map().is_allocation_contiguous();
359 }
360 
361 template <typename ViewType>
362 ViewType
363 make_view(const std::string& label,
364  const typename CijkType<ViewType>::type& cijk,
365  size_t N0 = 0, size_t N1 = 0, size_t N2 = 0, size_t N3 = 0,
366  size_t N4 = 0, size_t N5 = 0, size_t N6 = 0, size_t N7 = 0)
367 {
368  return ViewType(Experimental::view_alloc(label,cijk),
369  N0, N1, N2, N3, N4, N5, N6, N7);
370 }
371 
372 template <typename ViewType>
373 ViewType
374 make_view(const std::string& label,
375  const Experimental::Impl::WithoutInitializing_t& init,
376  const typename CijkType<ViewType>::type& cijk,
377  size_t N0 = 0, size_t N1 = 0, size_t N2 = 0, size_t N3 = 0,
378  size_t N4 = 0, size_t N5 = 0, size_t N6 = 0, size_t N7 = 0)
379 {
380  return ViewType(Experimental::view_alloc(label,init,cijk),
381  N0, N1, N2, N3, N4, N5, N6, N7);
382 }
383 
384 template <typename ViewType>
385 ViewType
386 make_view(const ViewAllocateWithoutInitializing& init,
387  const typename CijkType<ViewType>::type& cijk,
388  size_t N0 = 0, size_t N1 = 0, size_t N2 = 0, size_t N3 = 0,
389  size_t N4 = 0, size_t N5 = 0, size_t N6 = 0, size_t N7 = 0)
390 {
391  return ViewType(Experimental::view_alloc(init.label,
392  Experimental::WithoutInitializing,
393  cijk),
394  N0, N1, N2, N3, N4, N5, N6, N7);
395 }
396 
397 template <typename ViewType>
398 typename std::enable_if< is_view_uq_pce<ViewType>::value, ViewType>::type
399 make_view(typename ViewType::pointer_type ptr,
400  const typename CijkType<ViewType>::type& cijk,
401  size_t N0 = 0, size_t N1 = 0, size_t N2 = 0, size_t N3 = 0,
402  size_t N4 = 0, size_t N5 = 0, size_t N6 = 0, size_t N7 = 0)
403 {
404  size_t N[8] = { N0, N1, N2, N3, N4, N5, N6, N7 };
405  N[ViewType::rank] = cijk.dimension();
406  ViewType v(Experimental::view_wrap(ptr, cijk),
407  N[0], N[1], N[2], N[3], N[4], N[5], N[6], N[7]);
408  return v;
409 }
410 
411 } // namespace Kokkos
412 
413 //----------------------------------------------------------------------------
414 //----------------------------------------------------------------------------
415 //----------------------------------------------------------------------------
416 
417 namespace Kokkos {
418 //namespace Experimental {
419 namespace Impl {
420 
421 // Allow passing of Cijk tensor through ViewCtorProp
422 template< typename Value, typename Execution, typename Memory >
423 struct ViewCtorProp< void , Stokhos::CrsProductTensor<Value, Execution, Memory> >
424 {
425  ViewCtorProp() = default ;
426  ViewCtorProp( const ViewCtorProp & ) = default ;
427  ViewCtorProp & operator = ( const ViewCtorProp & ) = default ;
428 
430 
431  ViewCtorProp( const type & arg ) : value( arg ) {}
432  ViewCtorProp( type && arg ) : value( arg ) {}
433 
435 };
436 
437 template <typename AllocProp>
439 {
440  static const bool value = false;
441 };
442 
443 template< typename T >
444 struct ctor_prop_has_cijk< ViewCtorProp<T> >
445 {
446  static const bool value = false;
447 };
448 
449 template< typename Value, typename Execution, typename Memory >
451  ViewCtorProp< Stokhos::CrsProductTensor<Value, Execution, Memory> >
452  >
453 {
454  static const bool value = true;
455 };
456 
457 template< typename T, typename ... P >
458 struct ctor_prop_has_cijk< ViewCtorProp<T,P...> >
459 {
460  static const bool value =
462  ctor_prop_has_cijk< ViewCtorProp<P...> >::value;
463 };
464 
465 } /* namespace Impl */
466 //} /* namespace Experimental */
467 
468 template <typename CijkType, typename AllocProp>
469 KOKKOS_INLINE_FUNCTION
470 typename std::enable_if< !Impl::ctor_prop_has_cijk<AllocProp>::value,
471  CijkType >::type
472 extract_cijk(const AllocProp& prop)
473 {
474  return CijkType();
475 }
476 
477 template <typename CijkType, typename AllocProp>
478 KOKKOS_INLINE_FUNCTION
479 typename std::enable_if< Impl::ctor_prop_has_cijk<AllocProp>::value,
480  CijkType >::type
481 extract_cijk(const AllocProp& prop)
482 {
483  return ( (const Impl::ViewCtorProp<void,CijkType>&) prop ).value;
484 }
485 
486 } /* namespace Kokkos */
487 
488 //----------------------------------------------------------------------------
489 //----------------------------------------------------------------------------
490 //----------------------------------------------------------------------------
491 
492 namespace Kokkos {
493 namespace Experimental {
494 namespace Impl {
495 
496 template< class DataType , class ArrayLayout , typename StorageType >
497 struct ViewDataAnalysis< DataType /* Original view data type */
498  , ArrayLayout
499  , Sacado::UQ::PCE< StorageType > >
500 {
501 private:
502 
504  typedef ViewArrayAnalysis< DataType > array_analysis ;
505 
506 public:
507 
508  // Specialized view data mapping:
510 
511  typedef typename array_analysis::dimension dimension ;
513  typedef typename array_analysis::const_value_type const_value_type ;
514  typedef typename array_analysis::non_const_value_type non_const_value_type ;
515 
516  // Generate analogous multidimensional array specification type.
517  typedef typename
518  ViewDataType< value_type , dimension >::type type ;
519  typedef typename
520  ViewDataType< const_value_type , dimension >::type const_type ;
521  typedef typename
522  ViewDataType< non_const_value_type , dimension >::type non_const_type ;
523 
524 private:
525 
526  // A const ?
527  enum { is_const = std::is_same< value_type , const_value_type >::value };
528 
529  // The unwrapped scalar types:
530  typedef typename
531  std::conditional< is_const , const ScalarType , ScalarType >::type
533 
536 
537  // Prepend or append the pce dimension based on ArrayLayout
538  typedef typename array_analysis::dimension::
539  template prepend<0>::type
541  typedef typename array_analysis::dimension::
542  template append<0>::type
544  typedef typename std::conditional<
545  std::is_same< ArrayLayout, Kokkos::LayoutLeft>::value,
548 
549 public:
550 
551  // Generate "flattened" multidimensional array specification type.
552  typedef typename
553  ViewDataType< scalar_type , scalar_dimension >::type scalar_array_type ;
554 
555  typedef typename
556  ViewDataType< const_scalar_type , scalar_dimension >::type
558 
559  typedef typename
560  ViewDataType< non_const_scalar_type , scalar_dimension >::type
562 };
563 
564 } // namespace Impl
565 } // namespace Experimental
566 } // namespace Kokkos
567 
568 //----------------------------------------------------------------------------
569 
570 namespace Kokkos {
571 namespace Experimental {
572 namespace Impl {
573 
574 // UQ::PCE allocation for dynamically-sized UQ::PCE types.
575 // In this case we allocate two chunks of data, the first for the the
576 // UQ::PCE<Storage> itself and then for the underlying scalar type
577 // (UQ::PCE<Storage>::value_type). The memory is laid out with the
578 // former followed by the latter.
579 template <class ValueType>
581  typedef ValueType value_type;
582  typedef typename Sacado::ValueType<value_type>::type scalar_type;
583  typedef typename value_type::cijk_type cijk_type;
584 
587 
588  KOKKOS_INLINE_FUNCTION
589  static constexpr size_t
590  memory_span(const size_t span, const unsigned pce_size) {
591  return span * ( pce_size * sizeof(scalar_type) + sizeof(value_type) );
592  }
593 
594  KOKKOS_INLINE_FUNCTION
596 
597  template <typename T>
598  KOKKOS_INLINE_FUNCTION
600  value_ptr = a.value_ptr;
602  return *this;
603  }
604 
605  // We are making an assumption the data is laid out as described above,
606  // which in general may not be true if the view is created from memory
607  // allocated elsewhere. We should check for that.
608  KOKKOS_INLINE_FUNCTION
609  void set(value_type* ptr, const size_t span, const unsigned pce_size) {
610  value_ptr = ptr;
611  scalar_ptr = reinterpret_cast<scalar_type*>(ptr+span);
612  }
613 
614  template <class ExecSpace>
615  struct PCEConstruct {
616  ExecSpace m_space;
619  size_t m_span;
620  unsigned m_pce_size;
622 
623  PCEConstruct() = default;
624  PCEConstruct(const PCEConstruct&) = default;
625  PCEConstruct& operator=(const PCEConstruct&) = default;
626 
627  inline
628  PCEConstruct(const ExecSpace& space,
629  value_type* p,
630  scalar_type* sp,
631  const size_t span,
632  const unsigned pce_size,
633  const cijk_type& cijk) :
634  m_space(space), m_p(p), m_sp(sp), m_span(span), m_pce_size(pce_size),
635  m_cijk(cijk) {}
636 
637  inline void execute() {
638  if ( ! m_space.in_parallel() ) {
639  typedef Kokkos::RangePolicy< ExecSpace > PolicyType ;
640  const Kokkos::Impl::ParallelFor< PCEConstruct , PolicyType >
641  closure( *this , PolicyType( 0 , m_span ) );
642  closure.execute();
643  m_space.fence();
644  }
645  else {
646  for ( size_t i = 0 ; i < m_span ; ++i ) operator()(i);
647  }
648  }
649 
650  KOKKOS_INLINE_FUNCTION
651  void operator() (const size_t i) const {
652  new (m_p+i) value_type(m_cijk, m_pce_size, m_sp+i*m_pce_size, false);
653  }
654  };
655 
656  template <class ExecSpace>
658  typedef ViewValueFunctor< ExecSpace, scalar_type > ScalarFunctorType ;
663 
664  ConstructDestructFunctor() = default;
667 
668  ConstructDestructFunctor(const ExecSpace & space,
669  const bool initialize,
670  const size_t span,
671  const unsigned pce_size,
672  const cijk_type& cijk,
675  m_scalar_functor( space , scalar_ptr , span*pce_size ),
676  m_pce_functor( space , value_ptr , scalar_ptr , span , pce_size , cijk ),
677  m_initialize(initialize) {}
678 
680  // First initialize the scalar_type array
681  if (m_initialize)
682  m_scalar_functor.construct_shared_allocation();
683 
684  // Construct each UQ::PCE using memory in scalar_ptr array,
685  // setting pointer to UQ::PCE values from values array
686  // Equivalent to:
687  // value_type* p = value_ptr;
688  // scalar_type* sp = scalar_ptr;
689  // for (size_t i=0; i<span; ++i) {
690  // new (p++) value_type(cijk, pce_size, sp, false);
691  // sp += pce_size;
692  // }
693  // (we always need to do this, regardless of initialization)
695  }
696 
698  // We only need to (possibly) call the destructor on values in the
699  // scalar_type array, since the value_type array is a view into it
700  if (m_initialize)
701  m_scalar_functor.destroy_shared_allocation();
702  }
703 
704  };
705 
706  template <class ExecSpace>
707  inline ConstructDestructFunctor<ExecSpace>
708  create_functor(const ExecSpace & space,
709  const bool initialize,
710  const size_t span,
711  const unsigned pce_size,
712  const cijk_type& cijk) const {
713  return ConstructDestructFunctor<ExecSpace>(space, initialize, span,
714  pce_size, cijk, scalar_ptr,
715  value_ptr);
716  }
717 
718  // Assign scalar_type pointer to give ptr
719  // This makes BIG assumption on how the data was allocated
720  template <typename T>
721  void assign(T * ptr) {
722  value_ptr = reinterpret_cast<value_type*>(ptr);
723  if (ptr != 0)
724  scalar_ptr = value_ptr->coeff();
725  else
726  scalar_ptr = 0;
727  }
728 };
729 
730 template< class Traits >
731 class ViewMapping< Traits , /* View internal mapping */
732  typename std::enable_if<
733  ( std::is_same< typename Traits::specialize
734  , ViewPCEContiguous >::value
735  &&
736  ( std::is_same< typename Traits::array_layout
737  , Kokkos::LayoutLeft >::value
738  ||
739  std::is_same< typename Traits::array_layout
740  , Kokkos::LayoutRight >::value
741  ||
742  std::is_same< typename Traits::array_layout
743  , Kokkos::LayoutStride >::value
744  )
745  )>::type >
746 {
747 private:
748 
749  template< class , class ... > friend class ViewMapping ;
750  template< class , class ... > friend class Kokkos::Experimental::View ;
751 
752 public:
756  typedef typename
757  std::add_const< intrinsic_scalar_type >::type const_intrinsic_scalar_type ;
758  typedef typename sacado_uq_pce_type::cijk_type cijk_type ;
759 private:
760 
762 
763  typedef ViewOffset< typename Traits::dimension
764  , typename Traits::array_layout
765  , void
767 
768  // Prepend or append the pce dimension based on array_layout
769  typedef ViewArrayAnalysis< typename Traits::data_type > array_analysis ;
770  typedef typename array_analysis::dimension array_dimension;
771  typedef ViewOffset< typename array_dimension::
772  template append<0>::type,
773  typename Traits::array_layout,
774  void
776  typedef ViewOffset< typename array_dimension::
777  template prepend<0>::type,
778  typename Traits::array_layout,
779  void
781  typedef typename std::conditional<
782  std::is_same< typename Traits::array_layout, Kokkos::LayoutLeft>::value,
785 
788  unsigned m_sacado_size ; // Size of sacado dimension
789  cijk_type m_cijk ; // Sparse 3 tensor
790  bool m_is_contiguous ; // Is data allocated contiguously
791 
792  // Check whether data allocation is contiguous
793  // Since View() takes an arbitrary pointer, we can't necessarily assume
794  // the data was allocated contiguously
795  KOKKOS_INLINE_FUNCTION
796  bool is_data_contiguous() const {
797  const size_t sz = this->span();
798  if (sz == 0)
799  return true;
800  const intrinsic_scalar_type* last_coeff =
801  m_handle.value_ptr[sz-1].coeff();
802  const intrinsic_scalar_type* last_coeff_expected =
803  m_handle.scalar_ptr + (sz-1)*m_sacado_size;
804  return last_coeff == last_coeff_expected;
805  }
806 
807 public:
808 
809  //----------------------------------------
810  // Domain dimensions
811 
812  enum { Rank = Traits::dimension::rank };
813 
814  // Rank corresponding to the sacado dimension
815  enum { Sacado_Rank = std::is_same< typename Traits::array_layout, Kokkos::LayoutLeft >::value ? 0 : Rank+1 };
816 
817  // Using the internal offset mapping so limit to public rank:
818  template< typename iType >
819  KOKKOS_INLINE_FUNCTION constexpr size_t extent( const iType & r ) const
820  { return m_offset.m_dim.extent(r); }
821 
822  KOKKOS_INLINE_FUNCTION constexpr
823  typename Traits::array_layout layout() const
824  { return m_offset.layout(); }
825 
826  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_0() const
827  { return m_offset.dimension_0(); }
828  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const
829  { return m_offset.dimension_1(); }
830  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const
831  { return m_offset.dimension_2(); }
832  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const
833  { return m_offset.dimension_3(); }
834  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const
835  { return m_offset.dimension_4(); }
836  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const
837  { return m_offset.dimension_5(); }
838  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const
839  { return m_offset.dimension_6(); }
840  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const
841  { return m_offset.dimension_7(); }
842 
843  // Is a regular layout with uniform striding for each index.
844  // Since we all for striding within the data type, we can't guarantee
845  // regular striding
846  using is_regular = std::false_type ;
847 
848  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const
849  { return m_offset.stride_0(); }
850  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const
851  { return m_offset.stride_1(); }
852  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const
853  { return m_offset.stride_2(); }
854  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const
855  { return m_offset.stride_3(); }
856  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const
857  { return m_offset.stride_4(); }
858  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const
859  { return m_offset.stride_5(); }
860  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const
861  { return m_offset.stride_6(); }
862  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const
863  { return m_offset.stride_7(); }
864 
865  template< typename iType >
866  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const
867  { m_offset.stride(s); }
868 
869  // Size of sacado scalar dimension
870  KOKKOS_FORCEINLINE_FUNCTION constexpr unsigned dimension_scalar() const
871  { return m_sacado_size; }
872 
873  // Sparse tensor
874  KOKKOS_FORCEINLINE_FUNCTION
875  cijk_type cijk() const
876  { return m_cijk; }
877 
878  // Sparse tensor
879  KOKKOS_FORCEINLINE_FUNCTION
880  void set_cijk(const cijk_type& cijk)
881  { m_cijk = cijk; }
882 
883  // Is allocation contiguous
884  KOKKOS_INLINE_FUNCTION
886  { return m_is_contiguous; }
887 
888  // Whether the storage type is statically sized
889  static const bool is_static = false ;
890 
891  // Whether sacado dimension is contiguous
892  static const bool is_contiguous = true;
893 
894  //----------------------------------------
895  // Range of mapping
896 
897  // Return type of reference operators
899 
902 
904  KOKKOS_INLINE_FUNCTION constexpr size_t span() const
905  { return m_offset.span(); }
906 
908  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const
909  { return m_offset.span_is_contiguous() ; }
910 
912  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const
913  { return m_handle.value_ptr ; }
914 
915  //----------------------------------------
916 
917  KOKKOS_FORCEINLINE_FUNCTION
919  { return *m_handle.value_ptr; }
920 
921  // FIXME: Check this
922  template< typename I0 >
923  KOKKOS_FORCEINLINE_FUNCTION
924  typename
925  std::enable_if< std::is_integral<I0>::value &&
926  ! std::is_same< typename Traits::array_layout , Kokkos::LayoutStride >::value
927  , reference_type >::type
928  reference( const I0 & i0 ) const
929  { return m_handle.value_ptr[i0]; }
930 
931  // FIXME: Check this
932  template< typename I0 >
933  KOKKOS_FORCEINLINE_FUNCTION
934  typename
935  std::enable_if< std::is_integral<I0>::value &&
936  std::is_same< typename Traits::array_layout , Kokkos::LayoutStride >::value
937  , reference_type >::type
938  reference( const I0 & i0 ) const
939  { return m_handle.value_ptr[ m_offset(i0) ]; }
940 
941  template< typename I0 , typename I1 >
942  KOKKOS_FORCEINLINE_FUNCTION
943  reference_type reference( const I0 & i0 , const I1 & i1 ) const
944  { return m_handle.value_ptr[ m_offset(i0,i1) ]; }
945 
946  template< typename I0 , typename I1 , typename I2 >
947  KOKKOS_FORCEINLINE_FUNCTION
948  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 ) const
949  { return m_handle.value_ptr[ m_offset(i0,i1,i2) ]; }
950 
951  template< typename I0 , typename I1 , typename I2 , typename I3 >
952  KOKKOS_FORCEINLINE_FUNCTION
953  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3 ) const
954  { return m_handle.value_ptr[ m_offset(i0,i1,i2,i3) ]; }
955 
956  template< typename I0 , typename I1 , typename I2 , typename I3
957  , typename I4 >
958  KOKKOS_FORCEINLINE_FUNCTION
959  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
960  , const I4 & i4 ) const
961  { return m_handle.value_ptr[ m_offset(i0,i1,i2,i3,i4) ]; }
962 
963  template< typename I0 , typename I1 , typename I2 , typename I3
964  , typename I4 , typename I5 >
965  KOKKOS_FORCEINLINE_FUNCTION
966  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
967  , const I4 & i4 , const I5 & i5 ) const
968  { return m_handle.value_ptr[ m_offset(i0,i1,i2,i3,i4,i5) ]; }
969 
970  template< typename I0 , typename I1 , typename I2 , typename I3
971  , typename I4 , typename I5 , typename I6 >
972  KOKKOS_FORCEINLINE_FUNCTION
973  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
974  , const I4 & i4 , const I5 & i5 , const I6 & i6 ) const
975  { return m_handle.value_ptr[ m_offset(i0,i1,i2,i3,i4,i5,i6) ]; }
976 
977  template< typename I0 , typename I1 , typename I2 , typename I3
978  , typename I4 , typename I5 , typename I6 , typename I7 >
979  KOKKOS_FORCEINLINE_FUNCTION
980  reference_type reference( const I0 & i0 , const I1 & i1 , const I2 & i2 , const I3 & i3
981  , const I4 & i4 , const I5 & i5 , const I6 & i6 , const I7 & i7 ) const
982  { return m_handle.value_ptr[ m_offset(i0,i1,i2,i3,i4,i5,i6,i7) ]; }
983 
984  //----------------------------------------
985 
987  KOKKOS_INLINE_FUNCTION
988  static size_t memory_span( typename Traits::array_layout const & layout )
989  {
990  // Do not introduce padding...
991  typedef std::integral_constant< unsigned , 0 > padding ;
992  offset_type offset( padding(), layout );
993  unsigned sacado_size =
995  return handle_type::memory_span( offset.span(), sacado_size );
996  }
997 
998  //----------------------------------------
999 
1000  KOKKOS_INLINE_FUNCTION ~ViewMapping() = default ;
1001  KOKKOS_INLINE_FUNCTION ViewMapping() :
1002  m_handle(),
1003  m_offset(),
1004  m_sacado_size(0),
1005  m_cijk(),
1006  m_is_contiguous(true)
1007  {}
1008 
1009  KOKKOS_INLINE_FUNCTION ViewMapping( const ViewMapping & ) = default ;
1010  KOKKOS_INLINE_FUNCTION ViewMapping & operator = ( const ViewMapping & ) = default ;
1011 
1012  KOKKOS_INLINE_FUNCTION ViewMapping( ViewMapping && ) = default ;
1013  KOKKOS_INLINE_FUNCTION ViewMapping & operator = ( ViewMapping && ) = default ;
1014 
1015  template< class ... P >
1016  KOKKOS_INLINE_FUNCTION
1017  ViewMapping
1018  ( ViewCtorProp< P ... > const & prop
1019  , typename Traits::array_layout const & layout
1020  )
1021  : m_handle()
1022  , m_offset( std::integral_constant< unsigned , 0 >() , layout )
1023  , m_sacado_size( Kokkos::Impl::GetSacadoSize<unsigned(Rank)>::eval(layout) )
1024  {
1025  m_handle.set( ( (ViewCtorProp<void,pointer_type> const &) prop ).value
1026  , m_offset.span(), m_sacado_size );
1027  m_cijk = extract_cijk<cijk_type>(prop);
1028 #ifndef __CUDA_ARCH__
1029  if (m_cijk.dimension() == 0)
1030  m_cijk = getGlobalCijkTensor<cijk_type>();
1031  if (m_sacado_size == 0)
1032  m_sacado_size = m_cijk.dimension();
1033 #endif
1034  m_is_contiguous = this->is_data_contiguous();
1035  }
1036 
1037  //----------------------------------------
1038  /* Allocate and construct mapped array.
1039  * Allocate via shared allocation record and
1040  * return that record for allocation tracking.
1041  */
1042  template< class ... P >
1043  SharedAllocationRecord<> *
1044  allocate_shared( ViewCtorProp< P... > const & prop
1045  , typename Traits::array_layout const & layout )
1046  {
1047  typedef ViewCtorProp< P... > ctor_prop ;
1048 
1049  typedef typename ctor_prop::execution_space execution_space ;
1050  typedef typename Traits::memory_space memory_space ;
1051  typedef typename handle_type::template ConstructDestructFunctor<execution_space> functor_type ;
1052  typedef SharedAllocationRecord< memory_space , functor_type > record_type ;
1053 
1054  // Disallow padding
1055  typedef std::integral_constant< unsigned , 0 > padding ;
1056 
1057  m_offset = offset_type( padding(), layout );
1058  m_sacado_size = Kokkos::Impl::GetSacadoSize<unsigned(Rank)>::eval(layout);
1059  m_cijk = extract_cijk<cijk_type>(prop);
1060  if (m_cijk.dimension() == 0)
1061  m_cijk = getGlobalCijkTensor<cijk_type>();
1062  if (m_sacado_size == 0)
1063  m_sacado_size = m_cijk.dimension();
1064  m_is_contiguous = true;
1065 
1066  const size_t alloc_size =
1067  handle_type::memory_span( m_offset.span(), m_sacado_size );
1068 
1069  // Create shared memory tracking record with allocate memory from the memory space
1070  record_type * const record =
1071  record_type::allocate( ( (ViewCtorProp<void,memory_space> const &) prop ).value
1072  , ( (ViewCtorProp<void,std::string> const &) prop ).value
1073  , alloc_size );
1074 
1075  // Only set the the pointer and initialize if the allocation is non-zero.
1076  // May be zero if one of the dimensions is zero.
1077  if ( alloc_size ) {
1078 
1079  m_handle.set( reinterpret_cast< pointer_type >( record->data() ),
1080  m_offset.span(), m_sacado_size );
1081 
1082  // Assume destruction is only required when construction is requested.
1083  // The ViewValueFunctor has both value construction and destruction operators.
1084  record->m_destroy = m_handle.create_functor(
1085  ( (ViewCtorProp<void,execution_space> const &) prop).value
1086  , ctor_prop::initialize
1087  , m_offset.span()
1088  , m_sacado_size
1089  , m_cijk );
1090 
1091  // Construct values
1092  record->m_destroy.construct_shared_allocation();
1093  }
1094 
1095  return record ;
1096  }
1097 
1098 };
1099 
1100 } // namespace Impl
1101 } // namespace Experimental
1102 } // namespace Kokkos
1103 
1104 //----------------------------------------------------------------------------
1105 
1106 namespace Kokkos {
1107 namespace Experimental {
1108 namespace Impl {
1109 
1114 template< class DstTraits , class SrcTraits >
1115 class ViewMapping< DstTraits , SrcTraits ,
1116  typename std::enable_if<(
1117  std::is_same< typename DstTraits::memory_space
1118  , typename SrcTraits::memory_space >::value
1119  &&
1120  // Destination view has UQ::PCE
1121  std::is_same< typename DstTraits::specialize
1122  , ViewPCEContiguous >::value
1123  &&
1124  // Source view has UQ::PCE only
1125  std::is_same< typename SrcTraits::specialize
1126  , ViewPCEContiguous >::value
1127  )>::type >
1128 {
1129 public:
1130 
1131  enum { is_assignable = true };
1132 
1133  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
1134  typedef ViewMapping< DstTraits , void > DstType ;
1135  typedef ViewMapping< SrcTraits , void > SrcType ;
1136 
1137  KOKKOS_INLINE_FUNCTION static
1138  void assign( DstType & dst
1139  , const SrcType & src
1140  , const TrackType & )
1141  {
1142  static_assert(
1143  (
1144  std::is_same< typename DstTraits::array_layout
1145  , Kokkos::LayoutLeft >::value ||
1146  std::is_same< typename DstTraits::array_layout
1147  , Kokkos::LayoutRight >::value ||
1148  std::is_same< typename DstTraits::array_layout
1149  , Kokkos::LayoutStride >::value
1150  )
1151  &&
1152  (
1153  std::is_same< typename SrcTraits::array_layout
1154  , Kokkos::LayoutLeft >::value ||
1155  std::is_same< typename SrcTraits::array_layout
1156  , Kokkos::LayoutRight >::value ||
1157  std::is_same< typename SrcTraits::array_layout
1158  , Kokkos::LayoutStride >::value
1159  )
1160  , "View of UQ::PCE requires LayoutLeft, LayoutRight, or LayoutStride" );
1161 
1162  static_assert(
1163  std::is_same< typename DstTraits::array_layout
1164  , typename SrcTraits::array_layout >::value ||
1165  std::is_same< typename DstTraits::array_layout
1166  , Kokkos::LayoutStride >::value ||
1167  ( unsigned(DstTraits::rank) == 1 && unsigned(SrcTraits::rank) == 1 ) ,
1168  "View assignment must have compatible layout" );
1169 
1170  static_assert(
1171  std::is_same< typename DstTraits::value_type
1172  , typename SrcTraits::value_type >::value ||
1173  std::is_same< typename DstTraits::value_type
1174  , typename SrcTraits::const_value_type >::value ,
1175  "View assignment must have same value type or const = non-const" );
1176 
1177  static_assert(
1178  ViewDimensionAssignable
1179  < typename DstType::offset_type::dimension_type
1180  , typename SrcType::offset_type::dimension_type >::value ,
1181  "View assignment must have compatible dimensions" );
1182 
1183  dst.m_handle = src.m_handle ;
1184  dst.m_offset = src.m_offset ;
1185  dst.m_sacado_size = src.m_sacado_size ;
1186  dst.m_cijk = src.m_cijk ;
1187  dst.m_is_contiguous = src.m_is_contiguous ;
1188  }
1189 };
1190 
1196 template< class DstTraits , class SrcTraits >
1197 class ViewMapping< DstTraits , SrcTraits ,
1198  typename std::enable_if<(
1199  std::is_same< typename DstTraits::memory_space
1200  , typename SrcTraits::memory_space >::value
1201  &&
1202  // Destination view has ordinary
1203  std::is_same< typename DstTraits::specialize , void >::value
1204  &&
1205  // Source view has UQ::PCE only
1206  std::is_same< typename SrcTraits::specialize
1207  , ViewPCEContiguous >::value
1208  &&
1209  // Ranks match
1210  unsigned(DstTraits::dimension::rank) == unsigned(SrcTraits::dimension::rank)+1
1211  )>::type >
1212 {
1213 public:
1214 
1215  enum { is_assignable = true };
1216 
1217  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
1218  typedef ViewMapping< DstTraits , void > DstType ;
1219  typedef ViewMapping< SrcTraits , void > SrcType ;
1220 
1221  KOKKOS_INLINE_FUNCTION static
1222  void assign( DstType & dst
1223  , const SrcType & src
1224  , const TrackType & )
1225  {
1226  static_assert(
1227  (
1228  std::is_same< typename DstTraits::array_layout
1229  , Kokkos::LayoutLeft >::value ||
1230  std::is_same< typename DstTraits::array_layout
1231  , Kokkos::LayoutRight >::value ||
1232  std::is_same< typename DstTraits::array_layout
1233  , Kokkos::LayoutStride >::value
1234  )
1235  &&
1236  (
1237  std::is_same< typename SrcTraits::array_layout
1238  , Kokkos::LayoutLeft >::value ||
1239  std::is_same< typename SrcTraits::array_layout
1240  , Kokkos::LayoutRight >::value ||
1241  std::is_same< typename SrcTraits::array_layout
1242  , Kokkos::LayoutStride >::value
1243  )
1244  , "View of UQ::PCE requires LayoutLeft, LayoutRight, or LayoutStride" );
1245 
1246  static_assert(
1247  std::is_same< typename DstTraits::array_layout
1248  , typename SrcTraits::array_layout >::value ||
1249  std::is_same< typename DstTraits::array_layout
1250  , Kokkos::LayoutStride >::value ,
1251  "View assignment must have compatible layout" );
1252 
1253  static_assert(
1254  std::is_same< typename DstTraits::scalar_array_type
1255  , typename SrcTraits::scalar_array_type >::value ||
1256  std::is_same< typename DstTraits::scalar_array_type
1257  , typename SrcTraits::const_scalar_array_type >::value ,
1258  "View assignment must have same value type or const = non-const" );
1259 
1260  static_assert(
1261  ViewDimensionAssignable<
1262  typename DstType::offset_type::dimension_type,
1263  typename SrcType::array_offset_type::dimension_type >::value,
1264  "View assignment must have compatible dimensions" );
1265 
1266  if ( !src.m_is_contiguous )
1267  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::UQ::PCE ... >: can't assign non-contiguous view ******\n\n");
1268 
1269  unsigned dims[8];
1270  dims[0] = src.m_offset.dimension_0();
1271  dims[1] = src.m_offset.dimension_1();
1272  dims[2] = src.m_offset.dimension_2();
1273  dims[3] = src.m_offset.dimension_3();
1274  dims[4] = src.m_offset.dimension_4();
1275  dims[5] = src.m_offset.dimension_5();
1276  dims[6] = src.m_offset.dimension_6();
1277  dims[7] = src.m_offset.dimension_7();
1278  unsigned rank = SrcTraits::dimension::rank;
1279  unsigned sacado_size = src.m_sacado_size;
1280  if (std::is_same<typename SrcTraits::array_layout, LayoutLeft>::value) {
1281  // Move sacado_size to the first dimension, shift all others up one
1282  for (unsigned i=rank; i>0; --i)
1283  dims[i] = dims[i-1];
1284  dims[0] = sacado_size;
1285  }
1286  else {
1287  dims[rank] = sacado_size;
1288  }
1289  typedef typename DstType::offset_type dst_offset_type;
1290  dst.m_offset = dst_offset_type( std::integral_constant< unsigned , 0 >(),
1291  typename DstTraits::array_layout(
1292  dims[0] , dims[1] , dims[2] , dims[3] ,
1293  dims[4] , dims[5] , dims[6] , dims[7] ) );
1294  dst.m_handle = src.m_handle.scalar_ptr ;
1295  }
1296 };
1297 
1304 template< class DstTraits , class SrcTraits >
1305 class ViewMapping< DstTraits , SrcTraits ,
1306  typename std::enable_if<(
1307  std::is_same< typename DstTraits::memory_space
1308  , typename SrcTraits::memory_space >::value
1309  &&
1310  // Destination view has ordinary
1311  std::is_same< typename DstTraits::specialize , void >::value
1312  &&
1313  // Source view has UQ::PCE only
1314  std::is_same< typename SrcTraits::specialize
1315  , ViewPCEContiguous >::value
1316  &&
1317  // Ranks match
1318  unsigned(DstTraits::dimension::rank) == unsigned(SrcTraits::dimension::rank)
1319  )>::type >
1320 {
1321 public:
1322 
1323  enum { is_assignable = true };
1324 
1325  typedef Kokkos::Experimental::Impl::SharedAllocationTracker TrackType ;
1326  typedef ViewMapping< DstTraits , void > DstType ;
1327  typedef ViewMapping< SrcTraits , void > SrcType ;
1328 
1329  KOKKOS_INLINE_FUNCTION static
1330  void assign( DstType & dst
1331  , const SrcType & src
1332  , const TrackType & )
1333  {
1334  static_assert(
1335  (
1336  std::is_same< typename DstTraits::array_layout
1337  , Kokkos::LayoutLeft >::value ||
1338  std::is_same< typename DstTraits::array_layout
1339  , Kokkos::LayoutRight >::value ||
1340  std::is_same< typename DstTraits::array_layout
1341  , Kokkos::LayoutStride >::value
1342  )
1343  &&
1344  (
1345  std::is_same< typename SrcTraits::array_layout
1346  , Kokkos::LayoutLeft >::value ||
1347  std::is_same< typename SrcTraits::array_layout
1348  , Kokkos::LayoutRight >::value ||
1349  std::is_same< typename SrcTraits::array_layout
1350  , Kokkos::LayoutStride >::value
1351  )
1352  , "View of UQ::PCE requires LayoutLeft, LayoutRight, or LayoutStride" );
1353 
1354  static_assert(
1355  std::is_same< typename DstTraits::array_layout
1356  , typename SrcTraits::array_layout >::value ||
1357  std::is_same< typename DstTraits::array_layout
1358  , Kokkos::LayoutStride >::value ,
1359  "View assignment must have compatible layout" );
1360 
1361  static_assert(
1362  std::is_same< typename DstTraits::value_type
1363  , typename SrcTraits::non_const_value_type::value_type >::value ||
1364  std::is_same< typename DstTraits::value_type
1365  , const typename SrcTraits::non_const_value_type::value_type >::value ,
1366  "View assignment must have same value type or const = non-const" );
1367 
1368  static_assert(
1369  ViewDimensionAssignable<
1370  typename DstType::offset_type::dimension_type,
1371  typename SrcType::offset_type::dimension_type >::value,
1372  "View assignment must have compatible dimensions" );
1373 
1374  if ( !src.m_is_contiguous )
1375  Kokkos::abort("\n\n ****** Kokkos::View< Sacado::UQ::PCE ... >: can't assign non-contiguous view ******\n\n");
1376 
1377  unsigned dims[8];
1378  dims[0] = src.m_offset.dimension_0();
1379  dims[1] = src.m_offset.dimension_1();
1380  dims[2] = src.m_offset.dimension_2();
1381  dims[3] = src.m_offset.dimension_3();
1382  dims[4] = src.m_offset.dimension_4();
1383  dims[5] = src.m_offset.dimension_5();
1384  dims[6] = src.m_offset.dimension_6();
1385  dims[7] = src.m_offset.dimension_7();
1386  unsigned rank = SrcTraits::dimension::rank;
1387  unsigned sacado_size = src.m_sacado_size;
1388  if (std::is_same<typename DstTraits::array_layout, LayoutLeft>::value) {
1389  dims[0] = dims[0]*sacado_size;
1390  dims[rank] = 0;
1391  }
1392  else {
1393  dims[rank-1] = dims[rank-1]*sacado_size;
1394  dims[rank] = 0;
1395  }
1396  typedef typename DstType::offset_type dst_offset_type;
1397  dst.m_offset = dst_offset_type( std::integral_constant< unsigned , 0 >(),
1398  typename DstTraits::array_layout(
1399  dims[0] , dims[1] , dims[2] , dims[3] ,
1400  dims[4] , dims[5] , dims[6] , dims[7] ) );
1401  dst.m_handle = src.m_handle.scalar_ptr ;
1402  }
1403 };
1404 
1405 } // namespace Impl
1406 } // namespace Experimental
1407 } // namespace Kokkos
1408 
1409 //----------------------------------------------------------------------------
1410 
1411 namespace Kokkos {
1412 namespace Experimental {
1413 namespace Impl {
1414 
1415 // Subview mapping
1416 
1417 template< class DataType, class ... P , class Arg0, class ... Args >
1418 struct ViewMapping
1419  < typename std::enable_if<(
1420  // Source view has UQ::PCE only
1421  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::specialize
1422  , ViewPCEContiguous >::value
1423  &&
1424  (
1425  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::array_layout
1426  , Kokkos::LayoutLeft >::value ||
1427  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::array_layout
1428  , Kokkos::LayoutRight >::value ||
1429  std::is_same< typename Kokkos::Experimental::ViewTraits<DataType,P...>::array_layout
1430  , Kokkos::LayoutStride >::value
1431  )
1432  )>::type
1433  , Kokkos::Experimental::ViewTraits<DataType,P...>
1434  , Arg0, Args ... >
1435 {
1436 private:
1437 
1438  typedef Kokkos::Experimental::ViewTraits<DataType,P...> SrcTraits;
1439 
1440  //static_assert( SrcTraits::rank == sizeof...(Args) , "" );
1441 
1442  enum
1443  { RZ = false
1444  , R0 = bool(is_integral_extent<0,Arg0,Args...>::value)
1445  , R1 = bool(is_integral_extent<1,Arg0,Args...>::value)
1446  , R2 = bool(is_integral_extent<2,Arg0,Args...>::value)
1447  , R3 = bool(is_integral_extent<3,Arg0,Args...>::value)
1448  , R4 = bool(is_integral_extent<4,Arg0,Args...>::value)
1449  , R5 = bool(is_integral_extent<5,Arg0,Args...>::value)
1450  , R6 = bool(is_integral_extent<6,Arg0,Args...>::value)
1451  };
1452 
1453  // Public rank
1454  enum { rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
1455  + unsigned(R4) + unsigned(R5) + unsigned(R6) };
1456 
1457  // Whether right-most non-UQ::PCE rank is a range.
1458  enum { R0_rev = ( 0 == SrcTraits::rank ? RZ : (
1459  1 == SrcTraits::rank ? R0 : (
1460  2 == SrcTraits::rank ? R1 : (
1461  3 == SrcTraits::rank ? R2 : (
1462  4 == SrcTraits::rank ? R3 : (
1463  5 == SrcTraits::rank ? R4 : (
1464  6 == SrcTraits::rank ? R5 : R6 ))))))) };
1465 
1466  // Subview's layout
1467  typedef typename std::conditional<
1468  ( /* Same array layout IF */
1469  ( rank == 0 ) /* output rank zero */
1470  ||
1471  // OutputRank 1 or 2, InputLayout Left, Interval 0
1472  // because single stride one or second index has a stride.
1473  ( rank <= 2 && R0 && std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutLeft >::value )
1474  ||
1475  // OutputRank 1 or 2, InputLayout Right, Interval [InputRank-1]
1476  // because single stride one or second index has a stride.
1477  ( rank <= 2 && R0_rev && std::is_same< typename SrcTraits::array_layout , Kokkos::LayoutRight >::value )
1478  ), typename SrcTraits::array_layout , Kokkos::LayoutStride
1480 
1482 
1483  typedef typename std::conditional< rank == 0 , sacado_uq_pce_type ,
1484  typename std::conditional< rank == 1 , sacado_uq_pce_type * ,
1485  typename std::conditional< rank == 2 , sacado_uq_pce_type ** ,
1486  typename std::conditional< rank == 3 , sacado_uq_pce_type *** ,
1487  typename std::conditional< rank == 4 , sacado_uq_pce_type **** ,
1488  typename std::conditional< rank == 5 , sacado_uq_pce_type ***** ,
1489  typename std::conditional< rank == 6 , sacado_uq_pce_type ****** ,
1490  sacado_uq_pce_type *******
1493 
1494 public:
1495 
1496  typedef Kokkos::Experimental::ViewTraits
1497  < data_type
1498  , array_layout
1499  , typename SrcTraits::device_type
1500  , typename SrcTraits::memory_traits > traits_type ;
1501 
1502  typedef Kokkos::Experimental::View
1503  < data_type
1504  , array_layout
1505  , typename SrcTraits::device_type
1506  , typename SrcTraits::memory_traits > type ;
1507 
1508 
1509  // The presumed type is 'ViewMapping< traits_type , void >'
1510  // However, a compatible ViewMapping is acceptable.
1511  template< class DstTraits >
1512  KOKKOS_INLINE_FUNCTION
1513  static void assign( ViewMapping< DstTraits , void > & dst
1514  , ViewMapping< SrcTraits , void > const & src
1515  , Arg0 arg0, Args ... args )
1516  {
1517  static_assert(
1518  ViewMapping< DstTraits , traits_type , void >::is_assignable ,
1519  "Subview destination type must be compatible with subview derived type" );
1520 
1521  typedef ViewMapping< DstTraits , void > DstType ;
1522  typedef typename DstType::offset_type dst_offset_type ;
1523 
1524  const SubviewExtents< SrcTraits::rank , rank >
1525  extents( src.m_offset.m_dim , arg0 , args... );
1526 
1527  const size_t offset = src.m_offset( extents.domain_offset(0)
1528  , extents.domain_offset(1)
1529  , extents.domain_offset(2)
1530  , extents.domain_offset(3)
1531  , extents.domain_offset(4)
1532  , extents.domain_offset(5)
1533  , extents.domain_offset(6)
1534  , extents.domain_offset(7) );
1535 
1536  dst.m_offset = dst_offset_type( src.m_offset , extents );
1537  dst.m_handle.value_ptr = src.m_handle.value_ptr + offset;
1538  dst.m_handle.scalar_ptr =
1539  src.m_handle.scalar_ptr + offset * src.m_sacado_size;
1540  dst.m_sacado_size = src.m_sacado_size;
1541  dst.m_cijk = src.m_cijk;
1542  dst.m_is_contiguous = src.m_is_contiguous;
1543  }
1544 
1545 };
1546 
1547 } // namespace Impl
1548 } // namespace Experimental
1549 } // namespace Kokkos
1550 
1551 //----------------------------------------------------------------------------
1552 //----------------------------------------------------------------------------
1553 //----------------------------------------------------------------------------
1554 
1555 namespace Kokkos {
1556 namespace Impl {
1557 
1558 // Specialization for deep_copy( view, view::value_type ) for Cuda
1559 #if defined( KOKKOS_HAVE_CUDA )
1560 template< class OutputView >
1561 struct ViewFill< OutputView ,
1562  typename std::enable_if< std::is_same< typename OutputView::specialize,
1563  Kokkos::Experimental::Impl::ViewPCEContiguous >::value &&
1564  std::is_same< typename OutputView::execution_space,
1565  Cuda >::value >::type >
1566 {
1567  typedef typename OutputView::const_value_type const_value_type ;
1568  typedef typename Sacado::ScalarType<const_value_type>::type scalar_type ;
1569  typedef typename OutputView::execution_space execution_space ;
1570  typedef typename OutputView::size_type size_type ;
1571 
1572  template <unsigned VectorLength>
1573  struct PCEKernel {
1574  typedef typename OutputView::execution_space execution_space ;
1575  const OutputView output;
1576  const_value_type input;
1577 
1578  PCEKernel( const OutputView & arg_out , const_value_type & arg_in ) :
1579  output(arg_out), input(arg_in) {}
1580 
1581  typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ;
1582 
1583  KOKKOS_INLINE_FUNCTION
1584  void operator()( const team_member & dev ) const
1585  {
1586  const size_type tidx = dev.team_rank() % VectorLength;
1587  const size_type tidy = dev.team_rank() / VectorLength;
1588  const size_type nrow = dev.team_size() / VectorLength;
1589  const size_type nvec = dimension_scalar(output);
1590 
1591  const size_type i0 = dev.league_rank() * nrow + tidy;
1592  if ( i0 >= output.dimension_0() ) return;
1593 
1594  for ( size_type i1 = 0 ; i1 < output.dimension_1() ; ++i1 ) {
1595  for ( size_type i2 = 0 ; i2 < output.dimension_2() ; ++i2 ) {
1596  for ( size_type i3 = 0 ; i3 < output.dimension_3() ; ++i3 ) {
1597  for ( size_type i4 = 0 ; i4 < output.dimension_4() ; ++i4 ) {
1598  for ( size_type i5 = 0 ; i5 < output.dimension_5() ; ++i5 ) {
1599  for ( size_type i6 = 0 ; i6 < output.dimension_6() ; ++i6 ) {
1600  for ( size_type i7 = 0 ; i7 < output.dimension_7() ; ++i7 ) {
1601  for ( size_type is = tidx ; is < nvec ; is+=VectorLength ) {
1602  output(i0,i1,i2,i3,i4,i5,i6,i7).fastAccessCoeff(is) =
1603  input.fastAccessCoeff(is) ;
1604  }}}}}}}}
1605  }
1606  };
1607 
1608  template <unsigned VectorLength>
1609  struct ScalarKernel {
1610  typedef typename OutputView::execution_space execution_space ;
1611  const OutputView output;
1612  const scalar_type input;
1613 
1614  ScalarKernel( const OutputView & arg_out , const scalar_type & arg_in ) :
1615  output(arg_out), input(arg_in) {}
1616 
1617  typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ;
1618  KOKKOS_INLINE_FUNCTION
1619  void operator()( const team_member & dev ) const
1620  {
1621  const size_type tidx = dev.team_rank() % VectorLength;
1622  const size_type tidy = dev.team_rank() / VectorLength;
1623  const size_type nrow = dev.team_size() / VectorLength;
1624  const size_type npce = dimension_scalar(output);
1625 
1626  const size_type i0 = dev.league_rank() * nrow + tidy;
1627  if ( i0 >= output.dimension_0() ) return;
1628 
1629  for ( size_type i1 = 0 ; i1 < output.dimension_1() ; ++i1 ) {
1630  for ( size_type i2 = 0 ; i2 < output.dimension_2() ; ++i2 ) {
1631  for ( size_type i3 = 0 ; i3 < output.dimension_3() ; ++i3 ) {
1632  for ( size_type i4 = 0 ; i4 < output.dimension_4() ; ++i4 ) {
1633  for ( size_type i5 = 0 ; i5 < output.dimension_5() ; ++i5 ) {
1634  for ( size_type i6 = 0 ; i6 < output.dimension_6() ; ++i6 ) {
1635  for ( size_type i7 = 0 ; i7 < output.dimension_7() ; ++i7 ) {
1636  for ( size_type is = tidx ; is < npce ; is+=VectorLength ) {
1637  output(i0,i1,i2,i3,i4,i5,i6,i7).fastAccessCoeff(is) =
1638  is == 0 ? input : scalar_type(0) ;
1639  }}}}}}}}
1640  }
1641  };
1642 
1643  ViewFill( const OutputView & output , const_value_type & input )
1644  {
1645  // Coalesced accesses are 128 bytes in size
1647  const unsigned vector_length =
1648  ( 128 + sizeof(scalar_type)-1 ) / sizeof(scalar_type);
1649 
1650  // 8 warps per block should give good occupancy
1651  const size_type block_size = 256;
1652 
1653  const size_type rows_per_block = block_size / vector_length;
1654  const size_type n = output.dimension_0();
1655  const size_type league_size = ( n + rows_per_block-1 ) / rows_per_block;
1656  const size_type team_size = rows_per_block * vector_length;
1657  Kokkos::TeamPolicy< execution_space > config( league_size, team_size );
1658 
1659  if (input.size() != dimension_scalar(output) && input.size() != 1)
1660  Kokkos::abort("ViewFill: Invalid input value size");
1661 
1662  if (input.size() == 1)
1663  parallel_for(
1664  config, ScalarKernel<vector_length>(output, input.fastAccessCoeff(0)) );
1665  else
1666  parallel_for( config, PCEKernel<vector_length>(output, input) );
1667  execution_space::fence();
1668  }
1669 
1670  ViewFill( const OutputView & output , const scalar_type & input )
1671  {
1672  // Coalesced accesses are 128 bytes in size
1674  const unsigned vector_length =
1675  ( 128 + sizeof(scalar_type)-1 ) / sizeof(scalar_type);
1676 
1677  // 8 warps per block should give good occupancy
1678  const size_type block_size = 256;
1679 
1680  const size_type rows_per_block = block_size / vector_length;
1681  const size_type n = output.dimension_0();
1682  const size_type league_size = ( n + rows_per_block-1 ) / rows_per_block;
1683  const size_type team_size = rows_per_block * vector_length;
1684  Kokkos::TeamPolicy< execution_space > config( league_size, team_size );
1685 
1686  parallel_for( config, ScalarKernel<vector_length>(output, input) );
1687  execution_space::fence();
1688  }
1689 
1690 };
1691 #endif /* #if defined( KOKKOS_HAVE_CUDA ) */
1692 
1693 } // namespace Impl
1694 } // namespace Kokkos
1695 
1696 //----------------------------------------------------------------------------
1697 //----------------------------------------------------------------------------
1698 //----------------------------------------------------------------------------
1699 
1700 #endif /* #ifndef KOKKOS_EXPERIMENTAL_VIEW_UQ_PCE_CONTIGUOUS_HPP */
static KOKKOS_INLINE_FUNCTION constexpr size_t memory_span(const size_t span, const unsigned pce_size)
Stokhos::StandardStorage< int, double > storage_type
KOKKOS_INLINE_FUNCTION PCEAllocation & operator=(const PCEAllocation< T > &a)
Kokkos::DefaultExecutionSpace execution_space
KOKKOS_INLINE_FUNCTION void operator()(const size_type i0) const
ConstructDestructFunctor< ExecSpace > create_functor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned pce_size, const cijk_type &cijk) const
ViewType make_view(const std::string &label, size_t N0=0, size_t N1=0, size_t N2=0, size_t N3=0, size_t N4=0, size_t N5=0, size_t N6=0, size_t N7=0)
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< view_type >::value, bool >::type is_allocation_contiguous(const view_type &view)
std::conditional< std::is_same< ArrayLayout, Kokkos::LayoutLeft >::value, prepend_scalar_dimension, append_scalar_dimension >::type scalar_dimension
DeepCopyNonContiguous(const OutputView &arg_out, const InputView &arg_in)
Top-level namespace for Stokhos classes and functions.
KOKKOS_INLINE_FUNCTION void operator()(const size_t i) const
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< View< T, P... > >::value, unsigned >::type dimension_scalar(const View< T, P... > &view)
ConstructDestructFunctor & operator=(const ConstructDestructFunctor &)=default
void deep_copy(const Stokhos::CrsMatrix< ValueType, DstDevice, Layout > &dst, const Stokhos::CrsMatrix< ValueType, SrcDevice, Layout > &src)
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< view_type >::value, typename CijkType< view_type >::type >::type cijk(const view_type &view)
ConstructDestructFunctor(const ExecSpace &space, const bool initialize, const size_t span, const unsigned pce_size, const cijk_type &cijk, scalar_type *scalar_ptr, value_type *value_ptr)
PCEConstruct(const ExecSpace &space, value_type *p, scalar_type *sp, const size_t span, const unsigned pce_size, const cijk_type &cijk)
KOKKOS_INLINE_FUNCTION std::enable_if< !Impl::ctor_prop_has_cijk< AllocProp >::value, CijkType >::type extract_cijk(const AllocProp &prop)
KOKKOS_INLINE_FUNCTION void set(value_type *ptr, const size_t span, const unsigned pce_size)
PCEConstruct & operator=(const PCEConstruct &)=default
std::conditional< rank==0, sacado_uq_pce_type, typename std::conditional< rank==1, sacado_uq_pce_type *, typename std::conditional< rank==2, sacado_uq_pce_type **, typename std::conditional< rank==3, sacado_uq_pce_type ***, typename std::conditional< rank==4, sacado_uq_pce_type ****, typename std::conditional< rank==5, sacado_uq_pce_type *****, typename std::conditional< rank==6, sacado_uq_pce_type ******, sacado_uq_pce_type *******>::type >::type >::type >::type >::type >::type >::type data_type